Compare commits

..

3 commits

Author SHA1 Message Date
vladimir.kuznetsov
d766a001e3 refactoring: all protocol models now work with c++ classes 2025-07-03 10:20:01 +08:00
vladimir.kuznetsov
65f60ab922 refactoring: replaced part of the code to work with new config classes 2025-06-26 09:57:29 +08:00
vladimir.kuznetsov
2d22a74b22 refactoring: added classes for working with server configs 2025-06-20 22:18:47 +08:00
114 changed files with 2948 additions and 2628 deletions

View file

@ -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'

1
.gitmodules vendored
View file

@ -7,7 +7,6 @@
[submodule "client/3rd-prebuilt"]
path = client/3rd-prebuilt
url = https://github.com/amnezia-vpn/3rd-prebuilt
branch = feature/special-handshake
[submodule "client/3rd/amneziawg-apple"]
path = client/3rd/amneziawg-apple
url = https://github.com/amnezia-vpn/amneziawg-apple

View file

@ -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")
@ -28,7 +28,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
endif()
set(QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(APPLE AND NOT IOS)

@ -1 +1 @@
Subproject commit 840b7b070e6ac8b90dda2fac6e98859b23727c0c
Subproject commit 0f3748efd7cc04e0c914304b68931f925bed1259

@ -1 +1 @@
Subproject commit 811af0a83b3faeade89a9093a588595666d32066
Subproject commit 76e7db556a6d7e2582f9481df91db188a46c009c

View file

@ -120,21 +120,10 @@ 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("Itime")?.let { setItime(it.toInt()) }
}
private fun start(config: WireguardConfig, vpnBuilder: Builder, protect: (Int) -> Boolean) {

View file

@ -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,21 +117,10 @@ 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
internal var h4: Long? = null
internal var i1: String? = null
internal var i2: String? = null
internal var i3: String? = null
internal var i4: String? = null
internal var i5: String? = null
internal var j1: String? = null
internal var j2: String? = null
internal var j3: String? = null
internal var itime: Int? = null
fun setEndpoint(endpoint: InetEndpoint) = apply { this.endpoint = endpoint }
@ -183,21 +139,10 @@ 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 }
fun setH4(h4: Long) = apply { this.h4 = h4 }
fun setI1(i1: String) = apply { this.i1 = i1 }
fun setI2(i2: String) = apply { this.i2 = i2 }
fun setI3(i3: String) = apply { this.i3 = i3 }
fun setI4(i4: String) = apply { this.i4 = i4 }
fun setI5(i5: String) = apply { this.i5 = i5 }
fun setJ1(j1: String) = apply { this.j1 = j1 }
fun setJ2(j2: String) = apply { this.j2 = j2 }
fun setJ3(j3: String) = apply { this.j3 = j3 }
fun setItime(itime: Int) = apply { this.itime = itime }
override fun build(): WireguardConfig = configBuild().run { WireguardConfig(this@Builder) }
}

View file

@ -116,6 +116,7 @@ file(GLOB UI_MODELS_H CONFIGURE_DEPENDS
${CLIENT_ROOT_DIR}/ui/models/services/*.h
${CLIENT_ROOT_DIR}/ui/models/api/*.h
)
file(GLOB UI_MODELS_CPP CONFIGURE_DEPENDS
${CLIENT_ROOT_DIR}/ui/models/*.cpp
${CLIENT_ROOT_DIR}/ui/models/protocols/*.cpp
@ -127,17 +128,33 @@ file(GLOB UI_CONTROLLERS_H CONFIGURE_DEPENDS
${CLIENT_ROOT_DIR}/ui/controllers/*.h
${CLIENT_ROOT_DIR}/ui/controllers/api/*.h
)
file(GLOB UI_CONTROLLERS_CPP CONFIGURE_DEPENDS
${CLIENT_ROOT_DIR}/ui/controllers/*.cpp
${CLIENT_ROOT_DIR}/ui/controllers/api/*.cpp
)
file(GLOB CORE_MODELS_H CONFIGURE_DEPENDS
${CLIENT_ROOT_DIR}/core/models/*.h
${CLIENT_ROOT_DIR}/core/models/containers/*.h
${CLIENT_ROOT_DIR}/core/models/protocols/*.h
${CLIENT_ROOT_DIR}/core/models/servers/*.h
)
file(GLOB CORE_MODELS_CPP CONFIGURE_DEPENDS
${CLIENT_ROOT_DIR}/core/models/*.cpp
${CLIENT_ROOT_DIR}/core/models/containers/*.cpp
${CLIENT_ROOT_DIR}/core/models/protocols/*.cpp
${CLIENT_ROOT_DIR}/core/models/servers/*.cpp
)
set(HEADERS ${HEADERS}
${COMMON_FILES_H}
${PAGE_LOGIC_H}
${CONFIGURATORS_H}
${UI_MODELS_H}
${UI_CONTROLLERS_H}
${CORE_MODELS_H}
)
set(SOURCES ${SOURCES}
${COMMON_FILES_CPP}
@ -145,6 +162,7 @@ set(SOURCES ${SOURCES}
${CONFIGURATORS_CPP}
${UI_MODELS_CPP}
${UI_CONTROLLERS_CPP}
${CORE_MODELS_CPP}
)
if(WIN32)

View file

@ -1,5 +1,4 @@
#include "awg_configurator.h"
#include "protocols/protocols_defs.h"
#include <QJsonDocument>
#include <QJsonObject>
@ -40,20 +39,6 @@ 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::mtu] =
containerConfig.value(ProtocolProps::protoToString(Proto::Awg)).toObject().value(config_key::mtu).toString(protocols::awg::defaultMtu);

View file

@ -118,12 +118,6 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPair<QString,
QRegularExpression regex("redirect-gateway.*");
config.replace(regex, "");
// We don't use secondary DNS if primary DNS is AmneziaDNS
if (dns.first.contains(protocols::dns::amneziaDnsIp)) {
QRegularExpression dnsRegex("dhcp-option DNS " + dns.second);
config.replace(dnsRegex, "");
}
if (!m_settings->isSitesSplitTunnelingEnabled()) {
config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n");
config.append("block-ipv6\n");
@ -167,12 +161,6 @@ QString OpenVpnConfigurator::processConfigWithExportSettings(const QPair<QString
QRegularExpression regex("redirect-gateway.*");
config.replace(regex, "");
// We don't use secondary DNS if primary DNS is AmneziaDNS
if (dns.first.contains(protocols::dns::amneziaDnsIp)) {
QRegularExpression dnsRegex("dhcp-option DNS " + dns.second);
config.replace(dnsRegex, "");
}
config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n");
// Prevent ipv6 leak

View file

@ -14,11 +14,6 @@ namespace apiDefs
ExternalPremium
};
enum ConfigSource {
Telegram = 1,
AmneziaGateway
};
namespace key
{
constexpr QLatin1String configVersion("config_version");
@ -32,7 +27,6 @@ namespace apiDefs
constexpr QLatin1String stackType("stack_type");
constexpr QLatin1String serviceType("service_type");
constexpr QLatin1String cliVersion("cli_version");
constexpr QLatin1String supportedProtocols("supported_protocols");
constexpr QLatin1String vpnKey("vpn_key");
constexpr QLatin1String config("config");

View file

@ -32,8 +32,8 @@ bool apiUtils::isServerFromApi(const QJsonObject &serverConfigObject)
{
auto configVersion = serverConfigObject.value(apiDefs::key::configVersion).toInt();
switch (configVersion) {
case apiDefs::ConfigSource::Telegram: return true;
case apiDefs::ConfigSource::AmneziaGateway: return true;
case amnezia::ServerConfigType::ApiV1: return true;
case amnezia::ServerConfigType::ApiV2: return true;
default: return false;
}
}
@ -43,7 +43,7 @@ apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObjec
auto configVersion = serverConfigObject.value(apiDefs::key::configVersion).toInt();
switch (configVersion) {
case apiDefs::ConfigSource::Telegram: {
case amnezia::ServerConfigType::ApiV1: {
constexpr QLatin1String freeV2Endpoint(FREE_V2_ENDPOINT);
constexpr QLatin1String premiumV1Endpoint(PREM_V1_ENDPOINT);
@ -55,7 +55,7 @@ apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObjec
return apiDefs::ConfigType::AmneziaFreeV2;
}
};
case apiDefs::ConfigSource::AmneziaGateway: {
case amnezia::ServerConfigType::ApiV2: {
constexpr QLatin1String servicePremium("amnezia-premium");
constexpr QLatin1String serviceFree("amnezia-free");
constexpr QLatin1String serviceExternalPremium("external-premium");
@ -77,9 +77,9 @@ apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObjec
};
}
apiDefs::ConfigSource apiUtils::getConfigSource(const QJsonObject &serverConfigObject)
amnezia::ServerConfigType apiUtils::getConfigSource(const QJsonObject &serverConfigObject)
{
return static_cast<apiDefs::ConfigSource>(serverConfigObject.value(apiDefs::key::configVersion).toInt());
return static_cast<amnezia::ServerConfigType>(serverConfigObject.value(apiDefs::key::configVersion).toInt());
}
amnezia::ErrorCode apiUtils::checkNetworkReplyErrors(const QList<QSslError> &sslErrors, QNetworkReply *reply)

View file

@ -16,7 +16,7 @@ namespace apiUtils
bool isPremiumServer(const QJsonObject &serverConfigObject);
apiDefs::ConfigType getConfigType(const QJsonObject &serverConfigObject);
apiDefs::ConfigSource getConfigSource(const QJsonObject &serverConfigObject);
amnezia::ServerConfigType getConfigSource(const QJsonObject &serverConfigObject);
amnezia::ErrorCode checkNetworkReplyErrors(const QList<QSslError> &sslErrors, QNetworkReply *reply);

View file

@ -54,38 +54,43 @@ void CoreController::initModels()
m_appSplitTunnelingModel.reset(new AppSplitTunnelingModel(m_settings, this));
m_engine->rootContext()->setContextProperty("AppSplitTunnelingModel", m_appSplitTunnelingModel.get());
m_protocolsModel.reset(new ProtocolsModel(m_settings, this));
m_engine->rootContext()->setContextProperty("ProtocolsModel", m_protocolsModel.get());
m_openVpnConfigModel.reset(new OpenVpnConfigModel(this));
m_openVpnConfigModel = QSharedPointer<OpenVpnConfigModel>::create(this);
m_engine->rootContext()->setContextProperty("OpenVpnConfigModel", m_openVpnConfigModel.get());
m_shadowSocksConfigModel.reset(new ShadowSocksConfigModel(this));
m_shadowSocksConfigModel = QSharedPointer<ShadowSocksConfigModel>::create(this);
m_engine->rootContext()->setContextProperty("ShadowSocksConfigModel", m_shadowSocksConfigModel.get());
m_cloakConfigModel.reset(new CloakConfigModel(this));
m_cloakConfigModel = QSharedPointer<CloakConfigModel>::create(this);
m_engine->rootContext()->setContextProperty("CloakConfigModel", m_cloakConfigModel.get());
m_wireGuardConfigModel.reset(new WireGuardConfigModel(this));
m_wireGuardConfigModel = QSharedPointer<WireGuardConfigModel>::create(this);
m_engine->rootContext()->setContextProperty("WireGuardConfigModel", m_wireGuardConfigModel.get());
m_awgConfigModel.reset(new AwgConfigModel(this));
m_awgConfigModel = QSharedPointer<AwgConfigModel>::create(this);
m_engine->rootContext()->setContextProperty("AwgConfigModel", m_awgConfigModel.get());
m_xrayConfigModel.reset(new XrayConfigModel(this));
m_xrayConfigModel = QSharedPointer<XrayConfigModel>::create(this);
m_engine->rootContext()->setContextProperty("XrayConfigModel", m_xrayConfigModel.get());
#ifdef Q_OS_WINDOWS
m_ikev2ConfigModel.reset(new Ikev2ConfigModel(this));
m_ikev2ConfigModel = QSharedPointer<Ikev2ConfigModel>::create(this);
m_engine->rootContext()->setContextProperty("Ikev2ConfigModel", m_ikev2ConfigModel.get());
#endif
m_sftpConfigModel.reset(new SftpConfigModel(this));
m_sftpConfigModel = QSharedPointer<SftpConfigModel>::create(this);
m_engine->rootContext()->setContextProperty("SftpConfigModel", m_sftpConfigModel.get());
m_socks5ConfigModel.reset(new Socks5ProxyConfigModel(this));
m_socks5ConfigModel = QSharedPointer<Socks5ProxyConfigModel>::create(this);
m_engine->rootContext()->setContextProperty("Socks5ProxyConfigModel", m_socks5ConfigModel.get());
m_protocolsModel.reset(new ProtocolsModel(m_openVpnConfigModel, m_shadowSocksConfigModel, m_cloakConfigModel, m_wireGuardConfigModel,
m_awgConfigModel, m_xrayConfigModel,
#ifdef Q_OS_WINDOWS
m_ikev2ConfigModel,
#endif
m_sftpConfigModel, m_socks5ConfigModel, this));
m_engine->rootContext()->setContextProperty("ProtocolsModel", m_protocolsModel.get());
m_clientManagementModel.reset(new ClientManagementModel(m_settings, this));
m_engine->rootContext()->setContextProperty("ClientManagementModel", m_clientManagementModel.get());
@ -299,13 +304,10 @@ void CoreController::setQmlRoot()
void CoreController::initApiCountryModelUpdateHandler()
{
// TODO
connect(m_serversModel.get(), &ServersModel::updateApiCountryModel, this, [this]() {
m_apiCountryModel->updateModel(m_serversModel->getProcessedServerData("apiAvailableCountries").toJsonArray(),
m_serversModel->getProcessedServerData("apiServerCountryCode").toString());
});
connect(m_serversModel.get(), &ServersModel::updateApiServicesModel, this,
[this]() { m_apiServicesModel->updateModel(m_serversModel->getProcessedServerData("apiConfig").toJsonObject()); });
}
void CoreController::initContainerModelUpdateHandler()

View file

@ -129,17 +129,17 @@ private:
QSharedPointer<ApiAccountInfoModel> m_apiAccountInfoModel;
QSharedPointer<ApiDevicesModel> m_apiDevicesModel;
QScopedPointer<OpenVpnConfigModel> m_openVpnConfigModel;
QScopedPointer<ShadowSocksConfigModel> m_shadowSocksConfigModel;
QScopedPointer<CloakConfigModel> m_cloakConfigModel;
QScopedPointer<XrayConfigModel> m_xrayConfigModel;
QScopedPointer<WireGuardConfigModel> m_wireGuardConfigModel;
QScopedPointer<AwgConfigModel> m_awgConfigModel;
QSharedPointer<OpenVpnConfigModel> m_openVpnConfigModel;
QSharedPointer<ShadowSocksConfigModel> m_shadowSocksConfigModel;
QSharedPointer<CloakConfigModel> m_cloakConfigModel;
QSharedPointer<XrayConfigModel> m_xrayConfigModel;
QSharedPointer<WireGuardConfigModel> m_wireGuardConfigModel;
QSharedPointer<AwgConfigModel> m_awgConfigModel;
#ifdef Q_OS_WINDOWS
QScopedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
QSharedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
#endif
QScopedPointer<SftpConfigModel> m_sftpConfigModel;
QScopedPointer<Socks5ProxyConfigModel> m_socks5ConfigModel;
QSharedPointer<SftpConfigModel> m_sftpConfigModel;
QSharedPointer<Socks5ProxyConfigModel> m_socks5ConfigModel;
};
#endif // CORECONTROLLER_H

View file

@ -349,7 +349,7 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress)
!= newProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress))
|| (oldProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort)
!= newProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort))
!= newProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort))
|| (oldProtoConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount)
!= newProtoConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount))
|| (oldProtoConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize)
@ -366,13 +366,8 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
!= newProtoConfig.value(config_key::responsePacketMagicHeader).toString(protocols::awg::defaultResponsePacketMagicHeader))
|| (oldProtoConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader)
!= newProtoConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader))
|| (oldProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader))
!= newProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader))
// || (oldProtoConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize)
// != newProtoConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize))
// || (oldProtoConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize)
// != newProtoConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize))
|| (oldProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader)
!= newProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader)))
return true;
}
@ -380,7 +375,7 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress)
!= newProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress))
|| (oldProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)
!= newProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)))
!= newProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)))
return true;
}
@ -460,13 +455,11 @@ ErrorCode ServerController::buildContainerWorker(const ServerCredentials &creden
runScript(credentials,
replaceVars(amnezia::scriptData(SharedScriptType::build_container), genVarsForScript(credentials, container, config)),
cbReadStdOut, cbReadStdErr);
if (stdOut.contains("doesn't work on cgroups v2"))
return ErrorCode::ServerDockerOnCgroupsV2;
if (stdOut.contains("cgroup mountpoint does not exist"))
return ErrorCode::ServerCgroupMountpoint;
if (stdOut.contains("have reached") && stdOut.contains("pull rate limit"))
return ErrorCode::DockerPullRateLimit;
return error;
}
@ -646,9 +639,6 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
vars.append({ { "$UNDERLOAD_PACKET_MAGIC_HEADER", amneziaWireguarConfig.value(config_key::underloadPacketMagicHeader).toString() } });
vars.append({ { "$TRANSPORT_PACKET_MAGIC_HEADER", amneziaWireguarConfig.value(config_key::transportPacketMagicHeader).toString() } });
vars.append({ { "$COOKIE_REPLY_PACKET_JUNK_SIZE", amneziaWireguarConfig.value(config_key::cookieReplyPacketJunkSize).toString() } });
vars.append({ { "$TRANSPORT_PACKET_JUNK_SIZE", amneziaWireguarConfig.value(config_key::transportPacketJunkSize).toString() } });
// Socks5 proxy vars
vars.append({ { "$SOCKS5_PROXY_PORT", socks5ProxyConfig.value(config_key::port).toString(protocols::socks5Proxy::defaultPort) } });
auto username = socks5ProxyConfig.value(config_key::userName).toString();
@ -835,7 +825,7 @@ ErrorCode ServerController::isServerDpkgBusy(const ServerCredentials &credential
if (stdOut.contains("Packet manager not found"))
return ErrorCode::ServerPacketManagerError;
if (stdOut.contains("fuser not installed") || stdOut.contains("cat not installed"))
if (stdOut.contains("fuser not installed"))
return ErrorCode::NoError;
if (stdOut.isEmpty()) {

View file

@ -19,6 +19,13 @@ namespace amnezia
}
};
enum ServerConfigType
{
SelfHosted,
ApiV1,
ApiV2
};
struct InstalledAppInfo {
QString appName;
QString packageName;
@ -60,7 +67,6 @@ namespace amnezia
ServerUserPasswordRequired = 210,
ServerDockerOnCgroupsV2 = 211,
ServerCgroupMountpoint = 212,
DockerPullRateLimit = 213,
// Ssh connection errors
SshRequestDeniedError = 300,

View file

@ -28,7 +28,6 @@ QString errorString(ErrorCode code) {
case(ErrorCode::ServerUserPasswordRequired): errorMessage = QObject::tr("The user's password is required"); break;
case(ErrorCode::ServerDockerOnCgroupsV2): errorMessage = QObject::tr("Docker error: runc doesn't work on cgroups v2"); break;
case(ErrorCode::ServerCgroupMountpoint): errorMessage = QObject::tr("Server error: cgroup mountpoint does not exist"); break;
case(ErrorCode::DockerPullRateLimit): errorMessage = QObject::tr("Docker error: The pull rate limit has been reached"); break;
// Libssh errors
case(ErrorCode::SshRequestDeniedError): errorMessage = QObject::tr("SSH request was denied"); break;

View file

@ -0,0 +1,5 @@
#include "containerConfig.h"
ContainerConfig::ContainerConfig()
{
}

View file

@ -0,0 +1,19 @@
#ifndef CONTAINERCONFIG_H
#define CONTAINERCONFIG_H
#include <QMap>
#include <QSharedPointer>
#include <QString>
#include "core/models/protocols/protocolConfig.h"
class ContainerConfig
{
public:
ContainerConfig();
QString containerName;
QMap<QString, QSharedPointer<ProtocolConfig>> protocolConfigs;
};
#endif // CONTAINERCONFIG_H

View file

@ -0,0 +1,242 @@
#include "awgProtocolConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
AwgProtocolConfig::AwgProtocolConfig(const QString &protocolName) : ProtocolConfig(protocolName)
{
}
AwgProtocolConfig::AwgProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName) : ProtocolConfig(protocolName)
{
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
serverProtocolConfig.transportProto = protocolConfigObject.value(config_key::transport_proto).toString();
serverProtocolConfig.subnetAddress = protocolConfigObject.value(config_key::subnet_address).toString();
serverProtocolConfig.awgData.junkPacketCount = protocolConfigObject.value(config_key::junkPacketCount).toString();
serverProtocolConfig.awgData.junkPacketMinSize = protocolConfigObject.value(config_key::junkPacketMinSize).toString();
serverProtocolConfig.awgData.junkPacketMaxSize = protocolConfigObject.value(config_key::junkPacketMaxSize).toString();
serverProtocolConfig.awgData.initPacketJunkSize = protocolConfigObject.value(config_key::initPacketJunkSize).toString();
serverProtocolConfig.awgData.responsePacketJunkSize = protocolConfigObject.value(config_key::responsePacketJunkSize).toString();
serverProtocolConfig.awgData.initPacketMagicHeader = protocolConfigObject.value(config_key::initPacketMagicHeader).toString();
serverProtocolConfig.awgData.responsePacketMagicHeader = protocolConfigObject.value(config_key::responsePacketMagicHeader).toString();
serverProtocolConfig.awgData.underloadPacketMagicHeader = protocolConfigObject.value(config_key::underloadPacketMagicHeader).toString();
serverProtocolConfig.awgData.transportPacketMagicHeader = protocolConfigObject.value(config_key::transportPacketMagicHeader).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
QJsonObject clientProtocolConfigObject = QJsonDocument::fromJson(clientProtocolString.toUtf8()).object();
clientProtocolConfig.awgData.junkPacketCount = clientProtocolConfigObject.value(config_key::junkPacketCount).toString();
clientProtocolConfig.awgData.junkPacketMinSize = clientProtocolConfigObject.value(config_key::junkPacketMinSize).toString();
clientProtocolConfig.awgData.junkPacketMaxSize = clientProtocolConfigObject.value(config_key::junkPacketMaxSize).toString();
clientProtocolConfig.awgData.initPacketJunkSize = clientProtocolConfigObject.value(config_key::initPacketJunkSize).toString();
clientProtocolConfig.awgData.responsePacketJunkSize = clientProtocolConfigObject.value(config_key::responsePacketJunkSize).toString();
clientProtocolConfig.awgData.initPacketMagicHeader = clientProtocolConfigObject.value(config_key::initPacketMagicHeader).toString();
clientProtocolConfig.awgData.responsePacketMagicHeader =
clientProtocolConfigObject.value(config_key::responsePacketMagicHeader).toString();
clientProtocolConfig.awgData.underloadPacketMagicHeader =
clientProtocolConfigObject.value(config_key::underloadPacketMagicHeader).toString();
clientProtocolConfig.awgData.transportPacketMagicHeader =
clientProtocolConfigObject.value(config_key::transportPacketMagicHeader).toString();
clientProtocolConfig.clientId = clientProtocolConfigObject.value(config_key::clientId).toString();
clientProtocolConfig.wireGuardData.clientIp = clientProtocolConfigObject.value(config_key::client_ip).toString();
clientProtocolConfig.wireGuardData.clientPrivateKey = clientProtocolConfigObject.value(config_key::client_priv_key).toString();
clientProtocolConfig.wireGuardData.clientPublicKey = clientProtocolConfigObject.value(config_key::client_pub_key).toString();
clientProtocolConfig.wireGuardData.persistentKeepAlive =
clientProtocolConfigObject.value(config_key::persistent_keep_alive).toString();
clientProtocolConfig.wireGuardData.pskKey = clientProtocolConfigObject.value(config_key::psk_key).toString();
clientProtocolConfig.wireGuardData.serverPubKey = clientProtocolConfigObject.value(config_key::server_pub_key).toString();
clientProtocolConfig.wireGuardData.mtu = clientProtocolConfigObject.value(config_key::mtu).toString();
clientProtocolConfig.hostname = clientProtocolConfigObject.value(config_key::hostName).toString();
clientProtocolConfig.port = clientProtocolConfigObject.value(config_key::port).toInt(0);
clientProtocolConfig.nativeConfig = clientProtocolConfigObject.value(config_key::config).toString();
if (clientProtocolConfigObject.contains(config_key::allowed_ips)
&& clientProtocolConfigObject.value(config_key::allowed_ips).isArray()) {
auto allowedIpsArray = clientProtocolConfigObject.value(config_key::allowed_ips).toArray();
for (const auto &ip : allowedIpsArray) {
clientProtocolConfig.wireGuardData.allowedIps.append(ip.toString());
}
}
}
}
AwgProtocolConfig::AwgProtocolConfig(const AwgProtocolConfig &other) : ProtocolConfig(other.protocolName)
{
serverProtocolConfig = other.serverProtocolConfig;
clientProtocolConfig = other.clientProtocolConfig;
}
QJsonObject AwgProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.transportProto.isEmpty()) {
json[config_key::transport_proto] = serverProtocolConfig.transportProto;
}
if (!serverProtocolConfig.subnetAddress.isEmpty()) {
json[config_key::subnet_address] = serverProtocolConfig.subnetAddress;
}
if (!serverProtocolConfig.awgData.junkPacketCount.isEmpty()) {
json[config_key::junkPacketCount] = serverProtocolConfig.awgData.junkPacketCount;
}
if (!serverProtocolConfig.awgData.junkPacketMinSize.isEmpty()) {
json[config_key::junkPacketMinSize] = serverProtocolConfig.awgData.junkPacketMinSize;
}
if (!serverProtocolConfig.awgData.junkPacketMaxSize.isEmpty()) {
json[config_key::junkPacketMaxSize] = serverProtocolConfig.awgData.junkPacketMaxSize;
}
if (!serverProtocolConfig.awgData.initPacketJunkSize.isEmpty()) {
json[config_key::initPacketJunkSize] = serverProtocolConfig.awgData.initPacketJunkSize;
}
if (!serverProtocolConfig.awgData.responsePacketJunkSize.isEmpty()) {
json[config_key::responsePacketJunkSize] = serverProtocolConfig.awgData.responsePacketJunkSize;
}
if (!serverProtocolConfig.awgData.initPacketMagicHeader.isEmpty()) {
json[config_key::initPacketMagicHeader] = serverProtocolConfig.awgData.initPacketMagicHeader;
}
if (!serverProtocolConfig.awgData.responsePacketMagicHeader.isEmpty()) {
json[config_key::responsePacketMagicHeader] = serverProtocolConfig.awgData.responsePacketMagicHeader;
}
if (!serverProtocolConfig.awgData.underloadPacketMagicHeader.isEmpty()) {
json[config_key::underloadPacketMagicHeader] = serverProtocolConfig.awgData.underloadPacketMagicHeader;
}
if (!serverProtocolConfig.awgData.transportPacketMagicHeader.isEmpty()) {
json[config_key::transportPacketMagicHeader] = serverProtocolConfig.awgData.transportPacketMagicHeader;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;
if (!clientProtocolConfig.clientId.isEmpty()) {
clientConfigJson[config_key::clientId] = clientProtocolConfig.clientId;
}
if (!clientProtocolConfig.awgData.junkPacketCount.isEmpty()) {
clientConfigJson[config_key::junkPacketCount] = clientProtocolConfig.awgData.junkPacketCount;
}
if (!clientProtocolConfig.awgData.junkPacketMinSize.isEmpty()) {
clientConfigJson[config_key::junkPacketMinSize] = clientProtocolConfig.awgData.junkPacketMinSize;
}
if (!clientProtocolConfig.awgData.junkPacketMaxSize.isEmpty()) {
clientConfigJson[config_key::junkPacketMaxSize] = clientProtocolConfig.awgData.junkPacketMaxSize;
}
if (!clientProtocolConfig.awgData.initPacketJunkSize.isEmpty()) {
clientConfigJson[config_key::initPacketJunkSize] = clientProtocolConfig.awgData.initPacketJunkSize;
}
if (!clientProtocolConfig.awgData.responsePacketJunkSize.isEmpty()) {
clientConfigJson[config_key::responsePacketJunkSize] = clientProtocolConfig.awgData.responsePacketJunkSize;
}
if (!clientProtocolConfig.awgData.initPacketMagicHeader.isEmpty()) {
clientConfigJson[config_key::initPacketMagicHeader] = clientProtocolConfig.awgData.initPacketMagicHeader;
}
if (!clientProtocolConfig.awgData.responsePacketMagicHeader.isEmpty()) {
clientConfigJson[config_key::responsePacketMagicHeader] = clientProtocolConfig.awgData.responsePacketMagicHeader;
}
if (!clientProtocolConfig.awgData.underloadPacketMagicHeader.isEmpty()) {
clientConfigJson[config_key::underloadPacketMagicHeader] = clientProtocolConfig.awgData.underloadPacketMagicHeader;
}
if (!clientProtocolConfig.awgData.transportPacketMagicHeader.isEmpty()) {
clientConfigJson[config_key::transportPacketMagicHeader] = clientProtocolConfig.awgData.transportPacketMagicHeader;
}
if (!clientProtocolConfig.wireGuardData.clientIp.isEmpty()) {
clientConfigJson[config_key::client_ip] = clientProtocolConfig.wireGuardData.clientIp;
}
if (!clientProtocolConfig.wireGuardData.clientPrivateKey.isEmpty()) {
clientConfigJson[config_key::client_priv_key] = clientProtocolConfig.wireGuardData.clientPrivateKey;
}
if (!clientProtocolConfig.wireGuardData.clientPublicKey.isEmpty()) {
clientConfigJson[config_key::client_pub_key] = clientProtocolConfig.wireGuardData.clientPublicKey;
}
if (!clientProtocolConfig.wireGuardData.persistentKeepAlive.isEmpty()) {
clientConfigJson[config_key::persistent_keep_alive] = clientProtocolConfig.wireGuardData.persistentKeepAlive;
}
if (!clientProtocolConfig.wireGuardData.pskKey.isEmpty()) {
clientConfigJson[config_key::psk_key] = clientProtocolConfig.wireGuardData.pskKey;
}
if (!clientProtocolConfig.wireGuardData.serverPubKey.isEmpty()) {
clientConfigJson[config_key::server_pub_key] = clientProtocolConfig.wireGuardData.serverPubKey;
}
if (!clientProtocolConfig.wireGuardData.mtu.isEmpty()) {
clientConfigJson[config_key::mtu] = clientProtocolConfig.wireGuardData.mtu;
}
if (!clientProtocolConfig.wireGuardData.allowedIps.isEmpty()) {
QJsonArray allowedIpsArray;
for (const auto &ip : clientProtocolConfig.wireGuardData.allowedIps) {
if (!ip.isEmpty()) {
allowedIpsArray.append(ip);
}
}
if (!allowedIpsArray.isEmpty()) {
clientConfigJson[config_key::allowed_ips] = allowedIpsArray;
}
}
if (!clientProtocolConfig.hostname.isEmpty()) {
clientConfigJson[config_key::hostName] = clientProtocolConfig.hostname;
}
if (clientProtocolConfig.port) {
clientConfigJson[config_key::port] = clientProtocolConfig.port;
}
if (!clientProtocolConfig.nativeConfig.isEmpty()) {
clientConfigJson[config_key::config] = clientProtocolConfig.nativeConfig;
}
if (!clientConfigJson.isEmpty()) {
json[config_key::last_config] = QString(QJsonDocument(clientConfigJson).toJson(QJsonDocument::Compact));
}
}
return json;
}
bool AwgProtocolConfig::hasEqualServerSettings(const AwgProtocolConfig &other) const
{
if (serverProtocolConfig.subnetAddress != other.serverProtocolConfig.subnetAddress
|| serverProtocolConfig.port != other.serverProtocolConfig.port
|| serverProtocolConfig.awgData.junkPacketCount != other.serverProtocolConfig.awgData.junkPacketCount
|| serverProtocolConfig.awgData.junkPacketMinSize != other.serverProtocolConfig.awgData.junkPacketMinSize
|| serverProtocolConfig.awgData.junkPacketMaxSize != other.serverProtocolConfig.awgData.junkPacketMaxSize
|| serverProtocolConfig.awgData.initPacketJunkSize != other.serverProtocolConfig.awgData.initPacketJunkSize
|| serverProtocolConfig.awgData.responsePacketJunkSize != other.serverProtocolConfig.awgData.responsePacketJunkSize
|| serverProtocolConfig.awgData.initPacketMagicHeader != other.serverProtocolConfig.awgData.initPacketMagicHeader
|| serverProtocolConfig.awgData.responsePacketMagicHeader != other.serverProtocolConfig.awgData.responsePacketMagicHeader
|| serverProtocolConfig.awgData.underloadPacketMagicHeader != other.serverProtocolConfig.awgData.underloadPacketMagicHeader
|| serverProtocolConfig.awgData.transportPacketMagicHeader != other.serverProtocolConfig.awgData.transportPacketMagicHeader) {
return false;
}
return true;
}
bool AwgProtocolConfig::hasEqualClientSettings(const AwgProtocolConfig &other) const
{
if (clientProtocolConfig.wireGuardData.mtu != other.clientProtocolConfig.wireGuardData.mtu
|| clientProtocolConfig.awgData.junkPacketCount != other.clientProtocolConfig.awgData.junkPacketCount
|| clientProtocolConfig.awgData.junkPacketMinSize != other.clientProtocolConfig.awgData.junkPacketMinSize
|| clientProtocolConfig.awgData.junkPacketMaxSize != other.clientProtocolConfig.awgData.junkPacketMaxSize) {
return false;
}
return true;
}
void AwgProtocolConfig::clearClientSettings()
{
clientProtocolConfig = awg::ClientProtocolConfig();
}

View file

@ -0,0 +1,74 @@
#ifndef AWGPROTOCOLCONFIG_H
#define AWGPROTOCOLCONFIG_H
#include <QJsonObject>
#include <QStringList>
#include "protocolConfig.h"
#include "wireguardProtocolConfig.h"
namespace awg
{
struct AwgData
{
QString junkPacketCount;
QString junkPacketMinSize;
QString junkPacketMaxSize;
QString initPacketJunkSize;
QString responsePacketJunkSize;
QString initPacketMagicHeader;
QString responsePacketMagicHeader;
QString underloadPacketMagicHeader;
QString transportPacketMagicHeader;
};
struct ServerProtocolConfig
{
QString port;
QString transportProto;
QString subnetAddress;
AwgData awgData;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
QString clientId;
wireguard::WireGuardData wireGuardData;
AwgData awgData;
QString hostname;
int port;
QString nativeConfig;
};
const int messageInitiationSize = 148;
const int messageResponseSize = 92;
}
class AwgProtocolConfig : public ProtocolConfig
{
public:
AwgProtocolConfig(const QString &protocolName);
AwgProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
AwgProtocolConfig(const AwgProtocolConfig &other);
QJsonObject toJson() const override;
bool hasEqualServerSettings(const AwgProtocolConfig &other) const;
bool hasEqualClientSettings(const AwgProtocolConfig &other) const;
void clearClientSettings();
awg::ServerProtocolConfig serverProtocolConfig;
awg::ClientProtocolConfig clientProtocolConfig;
};
#endif // AWGPROTOCOLCONFIG_H

View file

@ -0,0 +1,58 @@
#include "cloakProtocolConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
CloakProtocolConfig::CloakProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName) : ProtocolConfig(protocolName)
{
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
serverProtocolConfig.cipher = protocolConfigObject.value(config_key::cipher).toString();
serverProtocolConfig.site = protocolConfigObject.value(config_key::site).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
QJsonObject clientProtocolConfigObject = QJsonDocument::fromJson(clientProtocolString.toUtf8()).object();
}
}
QJsonObject CloakProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.cipher.isEmpty()) {
json[config_key::cipher] = serverProtocolConfig.cipher;
}
if (!serverProtocolConfig.site.isEmpty()) {
json[config_key::site] = serverProtocolConfig.site;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;
json[config_key::last_config] = QString(QJsonDocument(clientConfigJson).toJson());
}
return json;
}
bool CloakProtocolConfig::hasEqualServerSettings(const CloakProtocolConfig &other) const
{
if (serverProtocolConfig.port != other.serverProtocolConfig.port ||
serverProtocolConfig.cipher != other.serverProtocolConfig.cipher ||
serverProtocolConfig.site != other.serverProtocolConfig.site) {
return false;
}
return true;
}
void CloakProtocolConfig::clearClientSettings()
{
clientProtocolConfig = cloak::ClientProtocolConfig();
}

View file

@ -0,0 +1,38 @@
#ifndef CLOAKPROTOCOLCONFIG_H
#define CLOAKPROTOCOLCONFIG_H
#include <QJsonObject>
#include <QString>
#include "protocolConfig.h"
namespace cloak
{
struct ServerProtocolConfig
{
QString port;
QString cipher;
QString site;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
};
}
class CloakProtocolConfig : public ProtocolConfig
{
public:
CloakProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
QJsonObject toJson() const override;
bool hasEqualServerSettings(const CloakProtocolConfig &other) const;
void clearClientSettings();
cloak::ServerProtocolConfig serverProtocolConfig;
cloak::ClientProtocolConfig clientProtocolConfig;
};
#endif // CLOAKPROTOCOLCONFIG_H

View file

@ -0,0 +1,100 @@
#include "openvpnProtocolConfig.h"
#include "protocols/protocols_defs.h"
#include <QJsonDocument>
using namespace amnezia;
OpenVpnProtocolConfig::OpenVpnProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName)
: ProtocolConfig(protocolName)
{
serverProtocolConfig.subnetAddress = protocolConfigObject.value(config_key::subnet_address).toString();
serverProtocolConfig.transportProto = protocolConfigObject.value(config_key::transport_proto).toString();
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
serverProtocolConfig.ncpDisable = protocolConfigObject.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable);
serverProtocolConfig.hash = protocolConfigObject.value(config_key::hash).toString();
serverProtocolConfig.cipher = protocolConfigObject.value(config_key::cipher).toString();
serverProtocolConfig.tlsAuth = protocolConfigObject.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth);
serverProtocolConfig.blockOutsideDns =
protocolConfigObject.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns);
serverProtocolConfig.additionalClientConfig = protocolConfigObject.value(config_key::additional_client_config).toString();
serverProtocolConfig.additionalServerConfig = protocolConfigObject.value(config_key::additional_server_config).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
QJsonObject clientProtocolConfigObject = QJsonDocument::fromJson(clientProtocolString.toUtf8()).object();
clientProtocolConfig.clientId = clientProtocolConfigObject.value(config_key::clientId).toString();
clientProtocolConfig.nativeConfig = clientProtocolConfigObject.value(config_key::config).toString();
}
}
QJsonObject OpenVpnProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.subnetAddress.isEmpty()) {
json[config_key::subnet_address] = serverProtocolConfig.subnetAddress;
}
if (!serverProtocolConfig.transportProto.isEmpty()) {
json[config_key::transport_proto] = serverProtocolConfig.transportProto;
}
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
json[config_key::ncp_disable] = serverProtocolConfig.ncpDisable;
if (!serverProtocolConfig.hash.isEmpty()) {
json[config_key::hash] = serverProtocolConfig.hash;
}
if (!serverProtocolConfig.cipher.isEmpty()) {
json[config_key::cipher] = serverProtocolConfig.cipher;
}
json[config_key::tls_auth] = serverProtocolConfig.tlsAuth;
json[config_key::block_outside_dns] = serverProtocolConfig.blockOutsideDns;
if (!serverProtocolConfig.additionalClientConfig.isEmpty()) {
json[config_key::additional_client_config] = serverProtocolConfig.additionalClientConfig;
}
if (!serverProtocolConfig.additionalServerConfig.isEmpty()) {
json[config_key::additional_server_config] = serverProtocolConfig.additionalServerConfig;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;
if (!clientProtocolConfig.clientId.isEmpty()) {
clientConfigJson[config_key::clientId] = clientProtocolConfig.clientId;
}
if (!clientProtocolConfig.nativeConfig.isEmpty()) {
clientConfigJson[config_key::config] = clientProtocolConfig.nativeConfig;
}
if (!clientConfigJson.isEmpty()) {
json[config_key::last_config] = QString(QJsonDocument(clientConfigJson).toJson());
}
}
return json;
}
bool OpenVpnProtocolConfig::hasEqualServerSettings(const OpenVpnProtocolConfig &other) const
{
if (serverProtocolConfig.subnetAddress != other.serverProtocolConfig.subnetAddress
|| serverProtocolConfig.transportProto != other.serverProtocolConfig.transportProto
|| serverProtocolConfig.port != other.serverProtocolConfig.port
|| serverProtocolConfig.ncpDisable != other.serverProtocolConfig.ncpDisable
|| serverProtocolConfig.hash != other.serverProtocolConfig.hash || serverProtocolConfig.cipher != other.serverProtocolConfig.cipher
|| serverProtocolConfig.tlsAuth != other.serverProtocolConfig.tlsAuth
|| serverProtocolConfig.blockOutsideDns != other.serverProtocolConfig.blockOutsideDns
|| serverProtocolConfig.additionalClientConfig != other.serverProtocolConfig.additionalClientConfig
|| serverProtocolConfig.additionalServerConfig != other.serverProtocolConfig.additionalServerConfig) {
return false;
}
return true;
}
void OpenVpnProtocolConfig::clearClientSettings()
{
clientProtocolConfig = openvpn::ClientProtocolConfig();
}

View file

@ -0,0 +1,49 @@
#ifndef OPENVPNPROTOCOLCONFIG_H
#define OPENVPNPROTOCOLCONFIG_H
#include <QJsonObject>
#include <QString>
#include "protocolConfig.h"
namespace openvpn
{
struct ServerProtocolConfig
{
QString subnetAddress;
QString transportProto;
QString port;
bool ncpDisable;
QString hash;
QString cipher;
bool tlsAuth;
bool blockOutsideDns;
QString additionalClientConfig;
QString additionalServerConfig;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
QString clientId;
QString nativeConfig;
};
}
class OpenVpnProtocolConfig : public ProtocolConfig
{
public:
OpenVpnProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
QJsonObject toJson() const override;
bool hasEqualServerSettings(const OpenVpnProtocolConfig &other) const;
void clearClientSettings();
openvpn::ServerProtocolConfig serverProtocolConfig;
openvpn::ClientProtocolConfig clientProtocolConfig;
};
#endif // OPENVPNPROTOCOLCONFIG_H

View file

@ -0,0 +1,76 @@
#include "protocolConfig.h"
#include "core/models/protocols/awgProtocolConfig.h"
#include "core/models/protocols/cloakProtocolConfig.h"
#include "core/models/protocols/openvpnProtocolConfig.h"
#include "core/models/protocols/protocolConfig.h"
#include "core/models/protocols/shadowsocksProtocolConfig.h"
#include "core/models/protocols/wireguardProtocolConfig.h"
#include "core/models/protocols/xrayProtocolConfig.h"
#include "protocols/protocols_defs.h"
using namespace amnezia;
ProtocolConfig::ProtocolConfig(const QString &protocolName) : protocolName(protocolName)
{
}
ProtocolConfigVariant ProtocolConfig::getProtocolConfigVariant(const QSharedPointer<ProtocolConfig> &protocolConfig)
{
ProtocolConfigVariant variant;
auto proto = ProtocolProps::protoFromString(protocolConfig->protocolName);
switch (proto) {
case Proto::OpenVpn: variant = qSharedPointerCast<OpenVpnProtocolConfig>(protocolConfig); break;
case Proto::WireGuard: variant = qSharedPointerCast<WireGuardProtocolConfig>(protocolConfig); break;
case Proto::ShadowSocks: variant = qSharedPointerCast<ShadowsocksProtocolConfig>(protocolConfig); break;
case Proto::Cloak: variant = qSharedPointerCast<CloakProtocolConfig>(protocolConfig); break;
case Proto::Xray: variant = qSharedPointerCast<XrayProtocolConfig>(protocolConfig); break;
case Proto::Awg: variant = qSharedPointerCast<AwgProtocolConfig>(protocolConfig); break;
default: break;
}
return variant;
}
bool ProtocolConfig::isServerSettingsEqual(const QSharedPointer<ProtocolConfig> &other)
{
auto proto = ProtocolProps::protoFromString(protocolName);
switch (proto) {
case Proto::OpenVpn: {
auto thisConfig = qSharedPointerCast<OpenVpnProtocolConfig>(QSharedPointer<ProtocolConfig>(this));
auto otherConfig = qSharedPointerCast<OpenVpnProtocolConfig>(other);
return thisConfig->hasEqualServerSettings(*otherConfig.data());
}
case Proto::WireGuard: {
auto thisConfig = qSharedPointerCast<WireGuardProtocolConfig>(QSharedPointer<ProtocolConfig>(this));
auto otherConfig = qSharedPointerCast<WireGuardProtocolConfig>(other);
return thisConfig->hasEqualServerSettings(*otherConfig.data());
}
case Proto::ShadowSocks: {
auto thisConfig = qSharedPointerCast<ShadowsocksProtocolConfig>(QSharedPointer<ProtocolConfig>(this));
auto otherConfig = qSharedPointerCast<ShadowsocksProtocolConfig>(other);
return thisConfig->hasEqualServerSettings(*otherConfig.data());
}
case Proto::Cloak: {
auto thisConfig = qSharedPointerCast<CloakProtocolConfig>(QSharedPointer<ProtocolConfig>(this));
auto otherConfig = qSharedPointerCast<CloakProtocolConfig>(other);
return thisConfig->hasEqualServerSettings(*otherConfig.data());
}
case Proto::Xray: {
auto thisConfig = qSharedPointerCast<XrayProtocolConfig>(QSharedPointer<ProtocolConfig>(this));
auto otherConfig = qSharedPointerCast<XrayProtocolConfig>(other);
return thisConfig->hasEqualServerSettings(*otherConfig.data());
}
case Proto::Awg: {
auto thisConfig = qSharedPointerCast<AwgProtocolConfig>(QSharedPointer<ProtocolConfig>(this));
auto otherConfig = qSharedPointerCast<AwgProtocolConfig>(other);
return thisConfig->hasEqualServerSettings(*otherConfig.data());
}
default: return false;
}
}
QJsonObject ProtocolConfig::toJson() const
{
return QJsonObject();
}

View file

@ -0,0 +1,31 @@
#ifndef PROTOCOLCONFIG_H
#define PROTOCOLCONFIG_H
#include <QJsonObject>
#include <QSharedPointer>
#include <variant>
class OpenVpnProtocolConfig;
class WireGuardProtocolConfig;
class ShadowsocksProtocolConfig;
class CloakProtocolConfig;
class XrayProtocolConfig;
class AwgProtocolConfig;
using ProtocolConfigVariant =
std::variant<QSharedPointer<OpenVpnProtocolConfig>, QSharedPointer<WireGuardProtocolConfig>, QSharedPointer<ShadowsocksProtocolConfig>,
QSharedPointer<CloakProtocolConfig>, QSharedPointer<XrayProtocolConfig>, QSharedPointer<AwgProtocolConfig> >;
class ProtocolConfig
{
public:
ProtocolConfig(const QString &protocolName);
virtual QJsonObject toJson() const;
static ProtocolConfigVariant getProtocolConfigVariant(const QSharedPointer<ProtocolConfig> &protocolConfig);
bool isServerSettingsEqual(const QSharedPointer<ProtocolConfig> &protocolConfig);
QString protocolName;
};
#endif // PROTOCOLCONFIG_H

View file

@ -0,0 +1,53 @@
#include "shadowsocksProtocolConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
ShadowsocksProtocolConfig::ShadowsocksProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName) : ProtocolConfig(protocolName)
{
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
serverProtocolConfig.cipher = protocolConfigObject.value(config_key::cipher).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
QJsonObject clientProtocolConfigObject = QJsonDocument::fromJson(clientProtocolString.toUtf8()).object();
}
}
QJsonObject ShadowsocksProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.cipher.isEmpty()) {
json[config_key::cipher] = serverProtocolConfig.cipher;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;
json[config_key::last_config] = QString(QJsonDocument(clientConfigJson).toJson());
}
return json;
}
bool ShadowsocksProtocolConfig::hasEqualServerSettings(const ShadowsocksProtocolConfig &other) const
{
if (serverProtocolConfig.port != other.serverProtocolConfig.port ||
serverProtocolConfig.cipher != other.serverProtocolConfig.cipher) {
return false;
}
return true;
}
void ShadowsocksProtocolConfig::clearClientSettings()
{
clientProtocolConfig = shadowsocks::ClientProtocolConfig();
}

View file

@ -0,0 +1,37 @@
#ifndef SHADOWSOCKSPROTOCOLCONFIG_H
#define SHADOWSOCKSPROTOCOLCONFIG_H
#include <QJsonObject>
#include <QString>
#include "protocolConfig.h"
namespace shadowsocks
{
struct ServerProtocolConfig
{
QString port;
QString cipher;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
};
}
class ShadowsocksProtocolConfig : public ProtocolConfig
{
public:
ShadowsocksProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
QJsonObject toJson() const override;
bool hasEqualServerSettings(const ShadowsocksProtocolConfig &other) const;
void clearClientSettings();
shadowsocks::ServerProtocolConfig serverProtocolConfig;
shadowsocks::ClientProtocolConfig clientProtocolConfig;
};
#endif // SHADOWSOCKSPROTOCOLCONFIG_H

View file

@ -0,0 +1,134 @@
#include "wireguardProtocolConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
WireGuardProtocolConfig::WireGuardProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName)
: ProtocolConfig(protocolName)
{
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
serverProtocolConfig.transportProto = protocolConfigObject.value(config_key::transport_proto).toString();
serverProtocolConfig.subnetAddress = protocolConfigObject.value(config_key::subnet_address).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
QJsonObject clientProtocolConfigObject = QJsonDocument::fromJson(clientProtocolString.toUtf8()).object();
clientProtocolConfig.clientId = clientProtocolConfigObject.value(config_key::clientId).toString();
clientProtocolConfig.wireGuardData.clientIp = clientProtocolConfigObject.value(config_key::client_ip).toString();
clientProtocolConfig.wireGuardData.clientPrivateKey = clientProtocolConfigObject.value(config_key::client_priv_key).toString();
clientProtocolConfig.wireGuardData.clientPublicKey = clientProtocolConfigObject.value(config_key::client_pub_key).toString();
clientProtocolConfig.wireGuardData.persistentKeepAlive =
clientProtocolConfigObject.value(config_key::persistent_keep_alive).toString();
clientProtocolConfig.wireGuardData.pskKey = clientProtocolConfigObject.value(config_key::psk_key).toString();
clientProtocolConfig.wireGuardData.serverPubKey = clientProtocolConfigObject.value(config_key::server_pub_key).toString();
clientProtocolConfig.wireGuardData.mtu = clientProtocolConfigObject.value(config_key::mtu).toString();
clientProtocolConfig.hostname = clientProtocolConfigObject.value(config_key::hostName).toString();
clientProtocolConfig.port = clientProtocolConfigObject.value(config_key::port).toInt(0);
clientProtocolConfig.nativeConfig = clientProtocolConfigObject.value(config_key::config).toString();
if (clientProtocolConfigObject.contains(config_key::allowed_ips)
&& clientProtocolConfigObject.value(config_key::allowed_ips).isArray()) {
auto allowedIpsArray = clientProtocolConfigObject.value(config_key::allowed_ips).toArray();
for (const auto &ip : allowedIpsArray) {
clientProtocolConfig.wireGuardData.allowedIps.append(ip.toString());
}
}
}
}
QJsonObject WireGuardProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.transportProto.isEmpty()) {
json[config_key::transport_proto] = serverProtocolConfig.transportProto;
}
if (!serverProtocolConfig.subnetAddress.isEmpty()) {
json[config_key::subnet_address] = serverProtocolConfig.subnetAddress;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;
if (!clientProtocolConfig.clientId.isEmpty()) {
clientConfigJson[config_key::clientId] = clientProtocolConfig.clientId;
}
if (!clientProtocolConfig.wireGuardData.clientIp.isEmpty()) {
clientConfigJson[config_key::client_ip] = clientProtocolConfig.wireGuardData.clientIp;
}
if (!clientProtocolConfig.wireGuardData.clientPrivateKey.isEmpty()) {
clientConfigJson[config_key::client_priv_key] = clientProtocolConfig.wireGuardData.clientPrivateKey;
}
if (!clientProtocolConfig.wireGuardData.clientPublicKey.isEmpty()) {
clientConfigJson[config_key::client_pub_key] = clientProtocolConfig.wireGuardData.clientPublicKey;
}
if (!clientProtocolConfig.wireGuardData.persistentKeepAlive.isEmpty()) {
clientConfigJson[config_key::persistent_keep_alive] = clientProtocolConfig.wireGuardData.persistentKeepAlive;
}
if (!clientProtocolConfig.wireGuardData.pskKey.isEmpty()) {
clientConfigJson[config_key::psk_key] = clientProtocolConfig.wireGuardData.pskKey;
}
if (!clientProtocolConfig.wireGuardData.serverPubKey.isEmpty()) {
clientConfigJson[config_key::server_pub_key] = clientProtocolConfig.wireGuardData.serverPubKey;
}
if (!clientProtocolConfig.wireGuardData.mtu.isEmpty()) {
clientConfigJson[config_key::mtu] = clientProtocolConfig.wireGuardData.mtu;
}
if (!clientProtocolConfig.wireGuardData.allowedIps.isEmpty()) {
QJsonArray allowedIpsArray;
for (const auto &ip : clientProtocolConfig.wireGuardData.allowedIps) {
if (!ip.isEmpty()) {
allowedIpsArray.append(ip);
}
}
if (!allowedIpsArray.isEmpty()) {
clientConfigJson[config_key::allowed_ips] = allowedIpsArray;
}
}
if (!clientProtocolConfig.hostname.isEmpty()) {
clientConfigJson[config_key::hostName] = clientProtocolConfig.hostname;
}
if (clientProtocolConfig.port) {
clientConfigJson[config_key::port] = clientProtocolConfig.port;
}
if (!clientProtocolConfig.nativeConfig.isEmpty()) {
clientConfigJson[config_key::config] = clientProtocolConfig.nativeConfig;
}
if (!clientConfigJson.isEmpty()) {
json[config_key::last_config] = QString(QJsonDocument(clientConfigJson).toJson());
}
}
return json;
}
bool WireGuardProtocolConfig::hasEqualServerSettings(const WireGuardProtocolConfig &other) const
{
if (serverProtocolConfig.subnetAddress != other.serverProtocolConfig.subnetAddress ||
serverProtocolConfig.port != other.serverProtocolConfig.port) {
return false;
}
return true;
}
void WireGuardProtocolConfig::clearClientSettings()
{
clientProtocolConfig = wireguard::ClientProtocolConfig();
}

View file

@ -0,0 +1,61 @@
#ifndef WIREGUARDPROTOCOLCONFIG_H
#define WIREGUARDPROTOCOLCONFIG_H
#include <QJsonObject>
#include <QStringList>
#include "protocolConfig.h"
namespace wireguard
{
struct WireGuardData
{
QStringList allowedIps;
QString clientIp;
QString clientPrivateKey;
QString clientPublicKey;
QString mtu;
QString persistentKeepAlive;
QString pskKey;
QString serverPubKey;
};
struct ServerProtocolConfig
{
QString port;
QString transportProto;
QString subnetAddress;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
QString clientId;
WireGuardData wireGuardData;
QString hostname;
int port;
QString nativeConfig;
};
}
class WireGuardProtocolConfig : public ProtocolConfig
{
public:
WireGuardProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
QJsonObject toJson() const override;
bool hasEqualServerSettings(const WireGuardProtocolConfig &other) const;
void clearClientSettings();
wireguard::ServerProtocolConfig serverProtocolConfig;
wireguard::ClientProtocolConfig clientProtocolConfig;
};
#endif // WIREGUARDPROTOCOLCONFIG_H

View file

@ -0,0 +1,58 @@
#include "xrayProtocolConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
XrayProtocolConfig::XrayProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName) : ProtocolConfig(protocolName)
{
serverProtocolConfig.site = protocolConfigObject.value(config_key::site).toString();
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString();
serverProtocolConfig.transportProto = protocolConfigObject.value(config_key::transport_proto).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
QJsonObject clientProtocolConfigObject = QJsonDocument::fromJson(clientProtocolString.toUtf8()).object();
}
}
QJsonObject XrayProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.site.isEmpty()) {
json[config_key::site] = serverProtocolConfig.site;
}
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.transportProto.isEmpty()) {
json[config_key::transport_proto] = serverProtocolConfig.transportProto;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;
json[config_key::last_config] = QString(QJsonDocument(clientConfigJson).toJson());
}
return json;
}
bool XrayProtocolConfig::hasEqualServerSettings(const XrayProtocolConfig &other) const
{
if (serverProtocolConfig.site != other.serverProtocolConfig.site ||
serverProtocolConfig.port != other.serverProtocolConfig.port ||
serverProtocolConfig.transportProto != other.serverProtocolConfig.transportProto) {
return false;
}
return true;
}
void XrayProtocolConfig::clearClientSettings()
{
clientProtocolConfig = xray::ClientProtocolConfig();
}

View file

@ -0,0 +1,38 @@
#ifndef XRAYPROTOCOLCONFIG_H
#define XRAYPROTOCOLCONFIG_H
#include <QJsonObject>
#include <QString>
#include "protocolConfig.h"
namespace xray
{
struct ServerProtocolConfig
{
QString site;
QString port;
QString transportProto;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
};
}
class XrayProtocolConfig : public ProtocolConfig
{
public:
XrayProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
QJsonObject toJson() const override;
bool hasEqualServerSettings(const XrayProtocolConfig &other) const;
void clearClientSettings();
xray::ServerProtocolConfig serverProtocolConfig;
xray::ClientProtocolConfig clientProtocolConfig;
};
#endif // XRAYPROTOCOLCONFIG_H

View file

@ -0,0 +1,28 @@
#include "apiV1ServerConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
ApiV1ServerConfig::ApiV1ServerConfig(const QJsonObject &serverConfigObject) : ServerConfig(serverConfigObject)
{
name = serverConfigObject.value(config_key::name).toString();
description = serverConfigObject.value(config_key::description).toString();
}
QJsonObject ApiV1ServerConfig::toJson() const
{
QJsonObject json = ServerConfig::toJson();
if (!name.isEmpty()) {
json[config_key::name] = name;
}
if (!description.isEmpty()) {
json[config_key::description] = description;
}
return json;
}

View file

@ -0,0 +1,17 @@
#ifndef APIV1SERVERCONFIG_H
#define APIV1SERVERCONFIG_H
#include "serverConfig.h"
class ApiV1ServerConfig : public ServerConfig
{
public:
ApiV1ServerConfig(const QJsonObject &serverConfigObject);
QJsonObject toJson() const override;
QString name;
QString description;
};
#endif // APIV1SERVERCONFIG_H

View file

@ -0,0 +1,125 @@
#include "apiV2ServerConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
ApiV2ServerConfig::ApiV2ServerConfig(const QJsonObject &serverConfigObject) : ServerConfig(serverConfigObject)
{
name = serverConfigObject.value(config_key::name).toString();
description = serverConfigObject.value(config_key::description).toString();
auto apiConfigObject = serverConfigObject.value("api_config").toObject();
auto availableCountriesArray = apiConfigObject.value("available_countries").toArray();
for (const auto &countryValue : availableCountriesArray) {
auto countryObject = countryValue.toObject();
apiv2::Country country;
country.code = countryObject.value("server_country_code").toString();
country.name = countryObject.value("server_country_name").toString();
apiConfig.availableCountries.append(country);
}
auto subscriptionObject = apiConfigObject.value("subscription").toObject();
apiConfig.subscription.end_date = subscriptionObject.value("end_date").toString();
auto publicKeyObject = apiConfigObject.value("public_key").toObject();
apiConfig.publicKey.expiresAt = publicKeyObject.value("expires_at").toString();
apiConfig.serverCountryCode = apiConfigObject.value("server_country_code").toString();
apiConfig.serverCountryName = apiConfigObject.value("server_country_name").toString();
apiConfig.serviceProtocol = apiConfigObject.value("service_protocol").toString();
apiConfig.serviceType = apiConfigObject.value("service_type").toString();
apiConfig.userCountryCode = apiConfigObject.value("user_country_code").toString();
apiConfig.vpnKey = apiConfigObject.value("vpn_key").toString();
auto authDataObject = serverConfigObject.value("auth_data").toObject();
apiConfig.authData.apiKey = authDataObject.value("api_key").toString();
}
QJsonObject ApiV2ServerConfig::toJson() const
{
QJsonObject json = ServerConfig::toJson();
if (!name.isEmpty()) {
json[config_key::name] = name;
}
if (!description.isEmpty()) {
json[config_key::description] = description;
}
QJsonObject apiConfigJson;
if (!apiConfig.availableCountries.isEmpty()) {
QJsonArray availableCountriesArray;
for (const auto &country : apiConfig.availableCountries) {
QJsonObject countryObject;
if (!country.code.isEmpty()) {
countryObject["server_country_code"] = country.code;
}
if (!country.name.isEmpty()) {
countryObject["server_country_name"] = country.name;
}
if (!countryObject.isEmpty()) {
availableCountriesArray.append(countryObject);
}
}
if (!availableCountriesArray.isEmpty()) {
apiConfigJson["available_countries"] = availableCountriesArray;
}
}
if (!apiConfig.subscription.end_date.isEmpty()) {
QJsonObject subscriptionObject;
subscriptionObject["end_date"] = apiConfig.subscription.end_date;
apiConfigJson["subscription"] = subscriptionObject;
}
if (!apiConfig.publicKey.expiresAt.isEmpty()) {
QJsonObject publicKeyObject;
publicKeyObject["expires_at"] = apiConfig.publicKey.expiresAt;
apiConfigJson["public_key"] = publicKeyObject;
}
if (!apiConfig.serverCountryCode.isEmpty()) {
apiConfigJson["server_country_code"] = apiConfig.serverCountryCode;
}
if (!apiConfig.serverCountryName.isEmpty()) {
apiConfigJson["server_country_name"] = apiConfig.serverCountryName;
}
if (!apiConfig.serviceProtocol.isEmpty()) {
apiConfigJson["service_protocol"] = apiConfig.serviceProtocol;
}
if (!apiConfig.serviceType.isEmpty()) {
apiConfigJson["service_type"] = apiConfig.serviceType;
}
if (!apiConfig.userCountryCode.isEmpty()) {
apiConfigJson["user_country_code"] = apiConfig.userCountryCode;
}
if (!apiConfig.vpnKey.isEmpty()) {
apiConfigJson["vpn_key"] = apiConfig.vpnKey;
}
QJsonObject authDataJson;
if (!apiConfig.authData.apiKey.isEmpty()) {
authDataJson["api_key"] = apiConfig.authData.apiKey;
}
if (!authDataJson.isEmpty()) {
apiConfigJson["auth_data"] = authDataJson;
}
if (!apiConfigJson.isEmpty()) {
json["api_config"] = apiConfigJson;
}
return json;
}

View file

@ -0,0 +1,61 @@
#ifndef APIV2SERVERCONFIG_H
#define APIV2SERVERCONFIG_H
#include "serverConfig.h"
namespace apiv2
{
struct Country {
QString code;
QString name;
};
struct PublicKey
{
QString expiresAt;
};
struct Subscription
{
QString end_date;
};
struct AuthData
{
QString apiKey;
};
struct ApiConfig {
QVector<Country> availableCountries;
Subscription subscription;
PublicKey publicKey;
AuthData authData;
QString serverCountryCode;
QString serverCountryName;
QString serviceProtocol;
QString serviceType;
QString userCountryCode;
QString vpnKey;
};
}
class ApiV2ServerConfig : public ServerConfig
{
public:
ApiV2ServerConfig(const QJsonObject &serverConfigObject);
QJsonObject toJson() const override;
QString name;
QString description;
apiv2::ApiConfig apiConfig;
};
#endif // APIV2SERVERCONFIG_H

View file

@ -0,0 +1,48 @@
#include "selfHostedServerConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
SelfHostedServerConfig::SelfHostedServerConfig(const QJsonObject &serverConfigObject) : ServerConfig(serverConfigObject)
{
name = serverConfigObject.value(config_key::description).toString();
if (name.isEmpty()) {
name = serverConfigObject.value(config_key::hostName).toString();
}
serverCredentials.hostName = serverConfigObject.value(config_key::hostName).toString();
serverCredentials.userName = serverConfigObject.value(config_key::userName).toString();
serverCredentials.secretData = serverConfigObject.value(config_key::password).toString();
serverCredentials.port = serverConfigObject.value(config_key::port).toInt(22);
}
QJsonObject SelfHostedServerConfig::toJson() const
{
// Сначала вызываем родительскую функцию для сериализации базовых полей
QJsonObject json = ServerConfig::toJson();
// Добавляем имя только если оно не пустое
if (!name.isEmpty()) {
json[config_key::description] = name; // Используем description как в конструкторе
}
// Добавляем credentials только если они не пустые
if (!serverCredentials.hostName.isEmpty()) {
json[config_key::hostName] = serverCredentials.hostName;
}
if (!serverCredentials.userName.isEmpty()) {
json[config_key::userName] = serverCredentials.userName;
}
if (!serverCredentials.secretData.isEmpty()) {
json[config_key::password] = serverCredentials.secretData;
}
if (serverCredentials.port != 22) { // Добавляем порт только если не дефолтный
json[config_key::port] = serverCredentials.port;
}
return json;
}

View file

@ -0,0 +1,19 @@
#ifndef SELFHOSTEDSERVERCONFIG_H
#define SELFHOSTEDSERVERCONFIG_H
#include "core/defs.h"
#include "serverConfig.h"
class SelfHostedServerConfig : public ServerConfig
{
public:
SelfHostedServerConfig(const QJsonObject &serverConfigObject);
QJsonObject toJson() const override;
QString name;
amnezia::ServerCredentials serverCredentials;
};
#endif // SELFHOSTEDSERVERCONFIG_H

View file

@ -0,0 +1,167 @@
#include "serverConfig.h"
#include <QJsonArray>
#include "apiV1ServerConfig.h"
#include "apiV2ServerConfig.h"
#include "containers/containers_defs.h"
#include "core/models/protocols/awgProtocolConfig.h"
#include "core/models/protocols/cloakProtocolConfig.h"
#include "core/models/protocols/openvpnProtocolConfig.h"
#include "core/models/protocols/protocolConfig.h"
#include "core/models/protocols/shadowsocksProtocolConfig.h"
#include "core/models/protocols/xrayProtocolConfig.h"
#include "protocols/protocols_defs.h"
#include "selfHostedServerConfig.h"
using namespace amnezia;
ServerConfig::ServerConfig(const QJsonObject &serverConfigObject)
{
type = static_cast<ServerConfigType>(serverConfigObject.value(config_key::configVersion).toInt(0));
hostName = serverConfigObject.value(config_key::hostName).toString();
dns1 = serverConfigObject.value(config_key::dns1).toString();
dns2 = serverConfigObject.value(config_key::dns2).toString();
defaultContainer = serverConfigObject.value(config_key::defaultContainer).toString();
crc = serverConfigObject.value(config_key::crc).toInt(0);
nameOverriddenByUser = serverConfigObject.value(config_key::nameOverriddenByUser).toBool(false);
auto containers = serverConfigObject.value(config_key::containers).toArray();
for (const auto &container : std::as_const(containers)) {
auto containerObject = container.toObject();
auto containerName = containerObject.value(config_key::container).toString();
ContainerConfig containerConfig;
containerConfig.containerName = containerName;
auto protocols = ContainerProps::protocolsForContainer(ContainerProps::containerFromString(containerName));
for (const auto &protocol : protocols) {
auto protocolName = ProtocolProps::protoToString(protocol);
auto protocolConfigObject = containerObject.value(protocolName).toObject();
switch (protocol) {
case Proto::OpenVpn: {
containerConfig.protocolConfigs.insert(protocolName,
QSharedPointer<OpenVpnProtocolConfig>::create(protocolConfigObject, protocolName));
break;
}
case Proto::ShadowSocks: {
containerConfig.protocolConfigs.insert(
protocolName, QSharedPointer<ShadowsocksProtocolConfig>::create(protocolConfigObject, protocolName));
break;
}
case Proto::Cloak: {
containerConfig.protocolConfigs.insert(protocolName,
QSharedPointer<CloakProtocolConfig>::create(protocolConfigObject, protocolName));
break;
}
case Proto::WireGuard: {
containerConfig.protocolConfigs.insert(protocolName,
QSharedPointer<WireGuardProtocolConfig>::create(protocolConfigObject, protocolName));
break;
}
case Proto::Awg: {
containerConfig.protocolConfigs.insert(protocolName,
QSharedPointer<AwgProtocolConfig>::create(protocolConfigObject, protocolName));
break;
}
case Proto::Xray: {
containerConfig.protocolConfigs.insert(protocolName,
QSharedPointer<XrayProtocolConfig>::create(protocolConfigObject, protocolName));
break;
}
case Proto::Ikev2: break;
case Proto::L2tp: break;
case Proto::SSXray: break;
case Proto::TorWebSite: break;
case Proto::Dns: break;
case Proto::Sftp: break;
case Proto::Socks5Proxy: break;
default: break;
}
}
containerConfigs.insert(containerName, containerConfig);
}
}
QSharedPointer<ServerConfig> ServerConfig::createServerConfig(const QJsonObject &serverConfigObject)
{
auto type = static_cast<ServerConfigType>(serverConfigObject.value(config_key::configVersion).toInt(0));
switch (type) {
case ServerConfigType::SelfHosted: return QSharedPointer<SelfHostedServerConfig>::create(serverConfigObject);
case ServerConfigType::ApiV1: return QSharedPointer<ApiV1ServerConfig>::create(serverConfigObject);
case ServerConfigType::ApiV2: return QSharedPointer<ApiV2ServerConfig>::create(serverConfigObject);
}
}
ServerConfigVariant ServerConfig::getServerConfigVariant(const QSharedPointer<ServerConfig> &serverConfig)
{
ServerConfigVariant variant;
switch (serverConfig->type) {
case amnezia::ServerConfigType::SelfHosted: variant = qSharedPointerCast<SelfHostedServerConfig>(serverConfig); break;
case amnezia::ServerConfigType::ApiV1: variant = qSharedPointerCast<ApiV1ServerConfig>(serverConfig); break;
case amnezia::ServerConfigType::ApiV2: variant = qSharedPointerCast<ApiV2ServerConfig>(serverConfig); break;
}
return variant;
}
QJsonObject ServerConfig::toJson() const
{
QJsonObject json;
if (type != ServerConfigType::SelfHosted) {
json[config_key::configVersion] = static_cast<int>(type);
}
if (!hostName.isEmpty()) {
json[config_key::hostName] = hostName;
}
if (!dns1.isEmpty()) {
json[config_key::dns1] = dns1;
}
if (!dns2.isEmpty()) {
json[config_key::dns2] = dns2;
}
if (!defaultContainer.isEmpty()) {
json[config_key::defaultContainer] = defaultContainer;
}
if (!containerConfigs.isEmpty()) {
QJsonArray containersArray;
for (const auto &containerConfig : containerConfigs) {
QJsonObject containerObject;
containerObject[config_key::container] = containerConfig.containerName;
if (!containerConfig.protocolConfigs.isEmpty()) {
for (const auto &protocolConfig : containerConfig.protocolConfigs) {
QJsonObject protocolJson = protocolConfig->toJson();
if (!protocolJson.isEmpty()) {
containerObject[protocolConfig->protocolName] = protocolJson;
}
}
}
containersArray.append(containerObject);
}
if (!containersArray.isEmpty()) {
json[config_key::containers] = containersArray;
}
}
return json;
}
void ServerConfig::updateProtocolConfig(const QString &containerName, const QMap<QString, QSharedPointer<ProtocolConfig>> &protocolConfigs)
{
if (containerConfigs.contains(containerName)) {
ContainerConfig &containerConfig = containerConfigs[containerName];
containerConfig.protocolConfigs = protocolConfigs;
}
}

View file

@ -0,0 +1,45 @@
#ifndef SERVERCONFIG_H
#define SERVERCONFIG_H
#include <QJsonObject>
#include <QSharedPointer>
#include <QString>
#include "core/defs.h"
#include "core/models/containers/containerConfig.h"
class SelfHostedServerConfig;
class ApiV1ServerConfig;
class ApiV2ServerConfig;
using ServerConfigVariant =
std::variant<QSharedPointer<SelfHostedServerConfig>, QSharedPointer<ApiV1ServerConfig>, QSharedPointer<ApiV2ServerConfig> >;
class ServerConfig
{
public:
ServerConfig(const QJsonObject &serverConfigObject);
virtual QJsonObject toJson() const;
static QSharedPointer<ServerConfig> createServerConfig(const QJsonObject &serverConfigObject);
static ServerConfigVariant getServerConfigVariant(const QSharedPointer<ServerConfig> &serverConfig);
void updateProtocolConfig(const QString &containerName, const QMap<QString, QSharedPointer<ProtocolConfig>> &protocolConfigs);
amnezia::ServerConfigType type;
QString hostName;
QString dns1;
QString dns2;
QString defaultContainer;
bool nameOverriddenByUser;
int crc; // TODO it makes sense to add for all server types or move it to the api
QMap<QString, ContainerConfig> containerConfigs;
};
#endif // SERVERCONFIG_H

View file

@ -169,14 +169,11 @@ bool Daemon::maybeUpdateResolvers(const InterfaceConfig& config) {
if ((config.m_hopType == InterfaceConfig::MultiHopExit) ||
(config.m_hopType == InterfaceConfig::SingleHop)) {
QList<QHostAddress> 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();
}
@ -425,34 +404,6 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) {
config.m_transportPacketMagicHeader = obj.value("H4").toString();
}
if (!obj.value("I1").isNull()) {
config.m_specialJunk["I1"] = obj.value("I1").toString();
}
if (!obj.value("I2").isNull()) {
config.m_specialJunk["I2"] = obj.value("I2").toString();
}
if (!obj.value("I3").isNull()) {
config.m_specialJunk["I3"] = obj.value("I3").toString();
}
if (!obj.value("I4").isNull()) {
config.m_specialJunk["I4"] = obj.value("I4").toString();
}
if (!obj.value("I5").isNull()) {
config.m_specialJunk["I5"] = obj.value("I5").toString();
}
if (!obj.value("J1").isNull()) {
config.m_controlledJunk["J1"] = obj.value("J1").toString();
}
if (!obj.value("J2").isNull()) {
config.m_controlledJunk["J2"] = obj.value("J2").toString();
}
if (!obj.value("J3").isNull()) {
config.m_controlledJunk["J3"] = obj.value("J3").toString();
}
if (!obj.value("Itime").isNull()) {
config.m_specialHandshakeTimeout = obj.value("Itime").toString();
}
return true;
}
@ -495,7 +446,7 @@ bool Daemon::deactivate(bool emitSignals) {
m_connections.clear();
// Delete the interface
return wgutils()->deleteInterface();
return wgutils()->deleteInterface();
}
QString Daemon::logs() {

View file

@ -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<QString, QString>& 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<QString, QString>& 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";
}
@ -149,16 +138,6 @@ QString InterfaceConfig::toWgConf(const QMap<QString, QString>& extra) const {
out << "H4 = " << m_transportPacketMagicHeader << "\n";
}
for (const QString& key : m_specialJunk.keys()) {
out << key << " = " << m_specialJunk[key] << "\n";
}
for (const QString& key : m_controlledJunk.keys()) {
out << key << " = " << m_controlledJunk[key] << "\n";
}
if (!m_specialHandshakeTimeout.isNull()) {
out << "Itime = " << m_specialHandshakeTimeout << "\n";
}
// If any extra config was provided, append it now.
for (const QString& key : extra.keys()) {
out << key << " = " << extra[key] << "\n";

View file

@ -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<IPAddress> m_allowedIPAddressRanges;
@ -50,15 +49,10 @@ 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;
QString m_transportPacketMagicHeader;
QMap<QString, QString> m_specialJunk;
QMap<QString, QString> m_controlledJunk;
QString m_specialHandshakeTimeout;
QJsonObject toJson() const;
QString toWgConf(

View file

@ -38,7 +38,7 @@ LocalSocketController::LocalSocketController() {
m_socket = new QLocalSocket(this);
connect(m_socket, &QLocalSocket::connected, this,
&LocalSocketController::daemonConnected);
connect(m_socket, &QLocalSocket::disconnected, this,
connect(m_socket, &QLocalSocket::disconnected, this,
[&] { errorOccurred(QLocalSocket::PeerClosedError); });
connect(m_socket, &QLocalSocket::errorOccurred, this,
&LocalSocketController::errorOccurred);
@ -135,7 +135,7 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
// set up IPv6 unique-local-address, ULA, with "fd00::/8" prefix, not globally routable.
// this will be default IPv6 gateway, OS recognizes that IPv6 link is local and switches to IPv4.
// Otherwise some OSes (Linux) try IPv6 forever and hang.
// Otherwise some OSes (Linux) try IPv6 forever and hang.
// https://en.wikipedia.org/wiki/Unique_local_address (RFC 4193)
// https://man7.org/linux/man-pages/man5/gai.conf.5.html
json.insert("deviceIpv6Address", "fd58:baa6:dead::1"); // simply "dead::1" is globally-routable, don't use it
@ -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,61 +237,28 @@ 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));
json.insert(amnezia::config_key::transportPacketMagicHeader, wgConfig.value(amnezia::config_key::transportPacketMagicHeader));
json.insert(amnezia::config_key::specialJunk1, wgConfig.value(amnezia::config_key::specialJunk1));
json.insert(amnezia::config_key::specialJunk2, wgConfig.value(amnezia::config_key::specialJunk2));
json.insert(amnezia::config_key::specialJunk3, wgConfig.value(amnezia::config_key::specialJunk3));
json.insert(amnezia::config_key::specialJunk4, wgConfig.value(amnezia::config_key::specialJunk4));
json.insert(amnezia::config_key::specialJunk5, wgConfig.value(amnezia::config_key::specialJunk5));
json.insert(amnezia::config_key::controlledJunk1, wgConfig.value(amnezia::config_key::controlledJunk1));
json.insert(amnezia::config_key::controlledJunk2, wgConfig.value(amnezia::config_key::controlledJunk2));
json.insert(amnezia::config_key::controlledJunk3, wgConfig.value(amnezia::config_key::controlledJunk3));
json.insert(amnezia::config_key::specialHandshakeTimeout, wgConfig.value(amnezia::config_key::specialHandshakeTimeout));
} else if (!wgConfig.value(amnezia::config_key::junkPacketCount).isUndefined()
&& !wgConfig.value(amnezia::config_key::junkPacketMinSize).isUndefined()
&& !wgConfig.value(amnezia::config_key::junkPacketMaxSize).isUndefined()
&& !wgConfig.value(amnezia::config_key::initPacketJunkSize).isUndefined()
&& !wgConfig.value(amnezia::config_key::responsePacketJunkSize).isUndefined()
&& !wgConfig.value(amnezia::config_key::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()
&& !wgConfig.value(amnezia::config_key::transportPacketMagicHeader).isUndefined()
&& !wgConfig.value(amnezia::config_key::specialJunk1).isUndefined()
&& !wgConfig.value(amnezia::config_key::specialJunk2).isUndefined()
&& !wgConfig.value(amnezia::config_key::specialJunk3).isUndefined()
&& !wgConfig.value(amnezia::config_key::specialJunk4).isUndefined()
&& !wgConfig.value(amnezia::config_key::specialJunk5).isUndefined()
&& !wgConfig.value(amnezia::config_key::controlledJunk1).isUndefined()
&& !wgConfig.value(amnezia::config_key::controlledJunk2).isUndefined()
&& !wgConfig.value(amnezia::config_key::controlledJunk3).isUndefined()
&& !wgConfig.value(amnezia::config_key::specialHandshakeTimeout).isUndefined()) {
&& !wgConfig.value(amnezia::config_key::transportPacketMagicHeader).isUndefined()) {
json.insert(amnezia::config_key::junkPacketCount, wgConfig.value(amnezia::config_key::junkPacketCount));
json.insert(amnezia::config_key::junkPacketMinSize, wgConfig.value(amnezia::config_key::junkPacketMinSize));
json.insert(amnezia::config_key::junkPacketMaxSize, wgConfig.value(amnezia::config_key::junkPacketMaxSize));
json.insert(amnezia::config_key::initPacketJunkSize, wgConfig.value(amnezia::config_key::initPacketJunkSize));
json.insert(amnezia::config_key::responsePacketJunkSize, wgConfig.value(amnezia::config_key::responsePacketJunkSize));
json.insert(amnezia::config_key::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));
json.insert(amnezia::config_key::transportPacketMagicHeader, wgConfig.value(amnezia::config_key::transportPacketMagicHeader));
json.insert(amnezia::config_key::specialJunk1, wgConfig.value(amnezia::config_key::specialJunk1));
json.insert(amnezia::config_key::specialJunk2, wgConfig.value(amnezia::config_key::specialJunk2));
json.insert(amnezia::config_key::specialJunk3, wgConfig.value(amnezia::config_key::specialJunk3));
json.insert(amnezia::config_key::specialJunk4, wgConfig.value(amnezia::config_key::specialJunk4));
json.insert(amnezia::config_key::specialJunk5, wgConfig.value(amnezia::config_key::specialJunk5));
json.insert(amnezia::config_key::controlledJunk1, wgConfig.value(amnezia::config_key::controlledJunk1));
json.insert(amnezia::config_key::controlledJunk2, wgConfig.value(amnezia::config_key::controlledJunk2));
json.insert(amnezia::config_key::controlledJunk3, wgConfig.value(amnezia::config_key::controlledJunk3));
json.insert(amnezia::config_key::specialHandshakeTimeout, wgConfig.value(amnezia::config_key::specialHandshakeTimeout));
}
write(json);

View file

@ -4,10 +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 specialJunk1, specialJunk2, specialJunk3, specialJunk4, specialJunk5: String?
let controlledJunk1, controlledJunk2, controlledJunk3: String?
let specialHandshakeTimeout: String?
let initPacketJunkSize, responsePacketJunkSize: String?
let dns1: String
let dns2: String
let mtu: String
@ -26,10 +23,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 specialJunk1 = "I1", specialJunk2 = "I2", specialJunk3 = "I3", specialJunk4 = "I4", specialJunk5 = "I5"
case controlledJunk1 = "J1", controlledJunk2 = "J2", controlledJunk3 = "J3"
case specialHandshakeTimeout = "Itime"
case initPacketJunkSize = "S1", responsePacketJunkSize = "S2"
case dns1
case dns2
case mtu
@ -46,59 +40,19 @@ 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!)")
junkPacketCount == nil ? "" :
"""
Jc = \(junkPacketCount!)
Jmin = \(junkPacketMinSize!)
Jmax = \(junkPacketMaxSize!)
S1 = \(initPacketJunkSize!)
S2 = \(responsePacketJunkSize!)
H1 = \(initPacketMagicHeader!)
H2 = \(responsePacketMagicHeader!)
H3 = \(underloadPacketMagicHeader!)
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")
"""
}
var str: String {

View file

@ -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;
}

View file

@ -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";
}
@ -140,26 +134,13 @@ bool WireguardUtilsLinux::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);
}
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()) {

View file

@ -43,16 +43,8 @@ namespace {
#include "macosfirewall.h"
#include <QDir>
#include <QStandardPaths>
// 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 <QProcess>
@ -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));
}

View file

@ -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);
}

View file

@ -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)) {

View file

@ -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);
}

View file

@ -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);

View file

@ -72,21 +72,10 @@ 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";
constexpr char transportPacketMagicHeader[] = "H4";
constexpr char specialJunk1[] = "I1";
constexpr char specialJunk2[] = "I2";
constexpr char specialJunk3[] = "I3";
constexpr char specialJunk4[] = "I4";
constexpr char specialJunk5[] = "I5";
constexpr char controlledJunk1[] = "J1";
constexpr char controlledJunk2[] = "J2";
constexpr char controlledJunk3[] = "J3";
constexpr char specialHandshakeTimeout[] = "Itime";
constexpr char openvpn[] = "openvpn";
constexpr char wireguard[] = "wireguard";
@ -227,22 +216,10 @@ 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";
constexpr char defaultUnderloadPacketMagicHeader[] = "1766607858";
constexpr char defaultSpecialJunk1[] = "";
constexpr char defaultSpecialJunk2[] = "";
constexpr char defaultSpecialJunk3[] = "";
constexpr char defaultSpecialJunk4[] = "";
constexpr char defaultSpecialJunk5[] = "";
constexpr char defaultControlledJunk1[] = "";
constexpr char defaultControlledJunk2[] = "";
constexpr char defaultControlledJunk3[] = "";
constexpr char defaultSpecialHandshakeTimeout[] = "";
}
namespace socks5Proxy

View file

@ -98,13 +98,8 @@ ErrorCode XrayProtocol::startTun2Sock()
if (vpnState == Vpn::ConnectionState::Connected) {
setConnectionState(Vpn::ConnectionState::Connecting);
QList<QHostAddress> 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);

View file

@ -239,7 +239,6 @@
<file>ui/qml/Components/ApiPremV1MigrationDrawer.qml</file>
<file>ui/qml/Components/ApiPremV1SubListDrawer.qml</file>
<file>ui/qml/Components/OtpCodeDrawer.qml</file>
<file>ui/qml/Components/AwgTextField.qml</file>
</qresource>
<qresource prefix="/countriesFlags">
<file>images/flagKit/ZW.svg</file>

View file

@ -10,7 +10,7 @@ RUN mkdir -p /opt/amnezia
RUN echo -e "#!/bin/bash\ntail -f /dev/null" > /opt/amnezia/start.sh
RUN chmod a+x /opt/amnezia/start.sh
# Tune network
# Tune network
RUN echo -e " \n\
fs.file-max = 51200 \n\
\n\
@ -40,8 +40,7 @@ RUN echo -e " \n\
echo -e " \n\
* soft nofile 51200 \n\
* hard nofile 51200 \n\
" | sed -e 's/^\s\+//g' | tee -a /etc/security/limits.conf
" | sed -e 's/^\s\+//g' | tee -a /etc/security/limits.conf
ENTRYPOINT [ "dumb-init", "/opt/amnezia/start.sh" ]
CMD [ "" ]

View file

@ -23,5 +23,4 @@ H1 = $INIT_PACKET_MAGIC_HEADER
H2 = $RESPONSE_PACKET_MAGIC_HEADER
H3 = $UNDERLOAD_PACKET_MAGIC_HEADER
H4 = $TRANSPORT_PACKET_MAGIC_HEADER
EOF

View file

@ -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

View file

@ -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;\

View file

@ -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";\

View file

@ -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("<key>", "<key>\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> &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,7 +259,7 @@ 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));
@ -463,13 +294,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 +305,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 +318,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 +329,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 +355,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 +366,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;
@ -568,16 +398,16 @@ bool ApiConfigsController::isConfigValid()
QJsonObject serverConfigObject = m_serversModel->getServerConfig(serverIndex);
auto configSource = apiUtils::getConfigSource(serverConfigObject);
if (configSource == apiDefs::ConfigSource::Telegram
if (configSource == amnezia::ServerConfigType::ApiV1
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
m_serversModel->removeApiConfig(serverIndex);
return updateServiceFromTelegram(serverIndex);
} else if (configSource == apiDefs::ConfigSource::AmneziaGateway
} else if (configSource == amnezia::ServerConfigType::ApiV2
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
return updateServiceFromGateway(serverIndex, "", "");
} else if (configSource && m_serversModel->isApiKeyExpired(serverIndex)) {
qDebug() << "attempt to update api config by expires_at event";
if (configSource == apiDefs::ConfigSource::AmneziaGateway) {
if (configSource == amnezia::ServerConfigType::ApiV2) {
return updateServiceFromGateway(serverIndex, "", "");
} else {
m_serversModel->removeApiConfig(serverIndex);
@ -587,29 +417,108 @@ 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("<key>", "<key>\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);
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() == amnezia::ServerConfigType::ApiV2) {
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() == amnezia::ServerConfigType::ApiV2) {
apiConfig.insert(configKey::serviceInfo, QJsonDocument::fromJson(apiResponseBody).object().value(configKey::serviceInfo).toObject());
}
serverConfig[configKey::apiConfig] = apiConfig;
return;
}
QList<QString> ApiConfigsController::getQrCodes()
@ -626,10 +535,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);
}

View file

@ -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<QString> getQrCodes();
int getQrCodesCount();
QString getVpnKey();
ErrorCode executeRequest(const QString &endpoint, const QJsonObject &apiPayload, QByteArray &responseBody);
QList<QString> m_qrCodes;
QString m_vpnKey;

View file

@ -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"
@ -287,19 +286,6 @@ void ImportController::processNativeWireGuardConfig()
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::isObfuscationEnabled] = true;
serverProtocolConfig[config_key::last_config] = QString(QJsonDocument(clientProtocolConfig).toJson());
@ -452,33 +438,21 @@ 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()) {
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);
protocolName = "awg";
m_configType = ConfigTypes::Awg;
}

View file

@ -11,6 +11,7 @@
#include "core/api/apiUtils.h"
#include "core/controllers/serverController.h"
#include "core/controllers/vpnConfigurationController.h"
#include "core/models/servers/selfHostedServerConfig.h"
#include "core/networkUtilities.h"
#include "logger.h"
#include "ui/models/protocols/awgConfigModel.h"
@ -79,36 +80,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<int> usedValues;
usedValues.insert(s1);
while (usedValues.contains(s2) || s1 + AwgConstant::messageInitiationSize == s2 + AwgConstant::messageResponseSize) {
while (s1 + awg::messageInitiationSize == s2 + awg::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<QString> headersValue;
while (headersValue.size() != 4) {
@ -132,21 +109,6 @@ void InstallController::install(DockerContainer container, int port, TransportPr
containerConfig[config_key::responsePacketMagicHeader] = responsePacketMagicHeader;
containerConfig[config_key::underloadPacketMagicHeader] = underloadPacketMagicHeader;
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;
// containerConfig[config_key::specialJunk4] = specialJunk4;
// containerConfig[config_key::specialJunk5] = specialJunk5;
// containerConfig[config_key::controlledJunk1] = controlledJunk1;
// containerConfig[config_key::controlledJunk2] = controlledJunk2;
// containerConfig[config_key::controlledJunk3] = controlledJunk3;
// containerConfig[config_key::specialHandshakeTimeout] = specialHandshakeTimeout;
} else if (container == DockerContainer::Sftp) {
containerConfig.insert(config_key::userName, protocols::sftp::defaultUserName);
containerConfig.insert(config_key::password, Utils::getRandomString(16));
@ -440,19 +402,6 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
containerConfig[config_key::transportPacketMagicHeader] =
serverConfigMap.value(config_key::transportPacketMagicHeader);
// 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,
protocols::wireguard::serverConfigPath, errorCode);
@ -604,28 +553,34 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
return ErrorCode::NoError;
}
void InstallController::updateContainer(QJsonObject config)
void InstallController::updateContainer()
{
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
auto oldServerConfig = m_serversModel->getServerConfig(serverIndex);
auto newServerConfig = QSharedPointer<SelfHostedServerConfig>::create(oldServerConfig);
const DockerContainer container = static_cast<DockerContainer>(m_containersModel->getProcessedContainerIndex());
const QString containerName = m_containersModel->getProcessedContainerName();
auto protocolConfigs = m_protocolModel->getProtocolConfigs();
newServerConfig->updateProtocolConfig(containerName, protocolConfigs);
auto oldProtocolConfigs = oldServerConfig->containerConfigs[containerName].protocolConfigs;
auto newProtocolConfigs = newServerConfig->containerConfigs[containerName].protocolConfigs;
const DockerContainer container = ContainerProps::containerFromString(config.value(config_key::container).toString());
QJsonObject oldContainerConfig = m_containersModel->getContainerConfig(container);
ErrorCode errorCode = ErrorCode::NoError;
if (isUpdateDockerContainerRequired(container, oldContainerConfig, config)) {
if (isUpdateDockerContainerRequired(container, oldProtocolConfigs, newProtocolConfigs)) {
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
connect(serverController.get(), &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
connect(this, &InstallController::cancelInstallation, serverController.get(), &ServerController::cancelInstallation);
errorCode = serverController->updateContainer(serverCredentials, container, oldContainerConfig, config);
errorCode = serverController->updateContainer(newServerConfig->serverCredentials, container, oldContainerConfig, config);
clearCachedProfile(serverController);
}
if (errorCode == ErrorCode::NoError) {
m_serversModel->updateContainerConfig(container, config);
m_protocolModel->updateModel(config);
m_serversModel->editServer(newServerConfig, serverIndex);
m_protocolModel->updateModel(protocolConfigs);
auto defaultContainer = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
if ((serverIndex == m_serversModel->getDefaultServerIndex()) && (container == defaultContainer)) {
@ -659,7 +614,7 @@ void InstallController::removeProcessedServer()
int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
m_serversModel->removeServer();
m_serversModel->removeProcessedServer();
emit removeProcessedServerFinished(tr("Server '%1' was removed").arg(serverName));
}
@ -965,29 +920,26 @@ bool InstallController::isConfigValid()
return true;
}
bool InstallController::isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig,
const QJsonObject &newConfig)
bool InstallController::isUpdateDockerContainerRequired(const DockerContainer container,
const QMap<QString, QSharedPointer<ProtocolConfig>> &oldProtocolConfigs,
const QMap<QString, QSharedPointer<ProtocolConfig>> &newProtocolConfigs)
{
Proto mainProto = ContainerProps::defaultProtocol(container);
const QJsonObject &oldProtoConfig = oldConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
const QJsonObject &newProtoConfig = newConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
const auto oldProtoConfig = oldProtocolConfigs.value(ProtocolProps::protoToString(mainProto));
const auto newProtoConfig = newProtocolConfigs.value(ProtocolProps::protoToString(mainProto));
if (container == DockerContainer::Awg) {
const AwgConfig oldConfig(oldProtoConfig);
const AwgConfig newConfig(newProtoConfig);
if (oldConfig.hasEqualServerSettings(newConfig)) {
return false;
}
} else if (container == DockerContainer::WireGuard) {
const WgConfig oldConfig(oldProtoConfig);
const WgConfig newConfig(newProtoConfig);
if (oldConfig.hasEqualServerSettings(newConfig)) {
return false;
}
switch (mainProto) {
case Proto::Awg: {
auto newConfig = qSharedPointerCast<AwgProtocolConfig>(oldProtoConfig);
auto oldConfig = qSharedPointerCast<AwgProtocolConfig>(newProtoConfig);
return !newConfig->hasEqualServerSettings(*oldConfig.data());
}
case Proto::WireGuard: {
auto newConfig = qSharedPointerCast<WireGuardProtocolConfig>(oldProtoConfig);
auto oldConfig = qSharedPointerCast<WireGuardProtocolConfig>(newProtoConfig);
return !newConfig->hasEqualServerSettings(*oldConfig.data());
}
default: return true;
}
return true;
}

View file

@ -28,7 +28,7 @@ public slots:
void scanServerForInstalledContainers();
void updateContainer(QJsonObject config);
void updateContainer();
void removeProcessedServer();
void rebootProcessedServer();
@ -94,7 +94,9 @@ private:
ErrorCode getAlreadyInstalledContainers(const ServerCredentials &credentials, const QSharedPointer<ServerController> &serverController,
QMap<DockerContainer, QJsonObject> &installedContainers);
bool isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig);
bool isUpdateDockerContainerRequired(const DockerContainer container,
const QMap<QString, QSharedPointer<ProtocolConfig>> &oldProtocolConfigs,
const QMap<QString, QSharedPointer<ProtocolConfig>> &newProtocolConfigs);
QSharedPointer<ServersModel> m_serversModel;
QSharedPointer<ContainersModel> m_containersModel;

View file

@ -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<int, QByteArray> ApiAccountInfoModel::roleNames() const
roles[ServiceDescriptionRole] = "serviceDescription";
roles[IsComponentVisibleRole] = "isComponentVisible";
roles[HasExpiredWorkerRole] = "hasExpiredWorker";
roles[IsProtocolSelectionSupportedRole] = "isProtocolSelectionSupported";
return roles;
}

View file

@ -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;

View file

@ -2,8 +2,7 @@
#include <QJsonArray>
ContainersModel::ContainersModel(QObject *parent)
: QAbstractListModel(parent)
ContainersModel::ContainersModel(QObject *parent) : QAbstractListModel(parent)
{
}
@ -25,19 +24,13 @@ QVariant ContainersModel::data(const QModelIndex &index, int role) const
case NameRole: return ContainerProps::containerHumanNames().value(container);
case DescriptionRole: return ContainerProps::containerDescriptions().value(container);
case DetailedDescriptionRole: return ContainerProps::containerDetailedDescriptions().value(container);
case ConfigRole: {
if (container == DockerContainer::None) {
return QJsonObject();
}
return m_containers.value(container);
}
case ServiceTypeRole: return ContainerProps::containerService(container);
case DockerContainerRole: return container;
case IsEasySetupContainerRole: return ContainerProps::isEasySetupContainer(container);
case EasySetupHeaderRole: return ContainerProps::easySetupHeader(container);
case EasySetupDescriptionRole: return ContainerProps::easySetupDescription(container);
case EasySetupOrderRole: return ContainerProps::easySetupOrder(container);
case IsInstalledRole: return m_containers.contains(container);
case IsInstalledRole: return m_containerConfigs.contains(ContainerProps::containerToString(container));
case IsCurrentlyProcessedRole: return container == static_cast<DockerContainer>(m_processedContainerIndex);
case IsSupportedRole: return ContainerProps::isSupportedByCurrentPlatform(container);
case IsShareableRole: return ContainerProps::isShareable(container);
@ -53,14 +46,10 @@ QVariant ContainersModel::data(const int index, int role) const
return data(modelIndex, role);
}
void ContainersModel::updateModel(const QJsonArray &containers)
void ContainersModel::updateModel(const QMap<QString, ContainerConfig> &containerConfigs)
{
beginResetModel();
m_containers.clear();
for (const QJsonValue &val : containers) {
m_containers.insert(ContainerProps::containerFromString(val.toObject().value(config_key::container).toString()),
val.toObject());
}
m_containerConfigs = containerConfigs;
endResetModel();
}
@ -79,11 +68,6 @@ QString ContainersModel::getProcessedContainerName()
return ContainerProps::containerHumanNames().value(static_cast<DockerContainer>(m_processedContainerIndex));
}
QJsonObject ContainersModel::getContainerConfig(const int containerIndex)
{
return qvariant_cast<QJsonObject>(data(index(containerIndex), ConfigRole));
}
bool ContainersModel::isSupportedByCurrentPlatform(const int containerIndex)
{
return qvariant_cast<bool>(data(index(containerIndex), IsSupportedRole));
@ -96,8 +80,8 @@ bool ContainersModel::isServiceContainer(const int containerIndex)
bool ContainersModel::hasInstalledServices()
{
for (const auto &container : m_containers.keys()) {
if (ContainerProps::containerService(container) == ServiceType::Other) {
for (const auto &containerName : m_containerConfigs.keys()) {
if (ContainerProps::containerService(ContainerProps::containerFromString(containerName)) == ServiceType::Other) {
return true;
}
}
@ -106,8 +90,8 @@ bool ContainersModel::hasInstalledServices()
bool ContainersModel::hasInstalledProtocols()
{
for (const auto &container : m_containers.keys()) {
if (ContainerProps::containerService(container) == ServiceType::Vpn) {
for (const auto &containerName : m_containerConfigs.keys()) {
if (ContainerProps::containerService(ContainerProps::containerFromString(containerName)) == ServiceType::Vpn) {
return true;
}
}
@ -122,7 +106,6 @@ QHash<int, QByteArray> ContainersModel::roleNames() const
roles[DetailedDescriptionRole] = "detailedDescription";
roles[ServiceTypeRole] = "serviceType";
roles[DockerContainerRole] = "dockerContainer";
roles[ConfigRole] = "config";
roles[IsEasySetupContainerRole] = "isEasySetupContainer";
roles[EasySetupHeaderRole] = "easySetupHeader";

View file

@ -3,10 +3,9 @@
#include <QAbstractListModel>
#include <QJsonObject>
#include <utility>
#include <vector>
#include "containers/containers_defs.h"
#include "core/models/containers/containerConfig.h"
class ContainersModel : public QAbstractListModel
{
@ -19,7 +18,6 @@ public:
DescriptionRole,
DetailedDescriptionRole,
ServiceTypeRole,
ConfigRole,
DockerContainerRole,
IsEasySetupContainerRole,
@ -42,15 +40,13 @@ public:
QVariant data(const int index, int role) const;
public slots:
void updateModel(const QJsonArray &containers);
void updateModel(const QMap<QString, ContainerConfig> &containerConfigs);
void setProcessedContainerIndex(int containerIndex);
int getProcessedContainerIndex();
QString getProcessedContainerName();
QJsonObject getContainerConfig(const int containerIndex);
bool isSupportedByCurrentPlatform(const int containerIndex);
bool isServiceContainer(const int containerIndex);
@ -64,7 +60,7 @@ signals:
void containersModelUpdated();
private:
QMap<DockerContainer, QJsonObject> m_containers;
QMap<QString, ContainerConfig> m_containerConfigs;
int m_processedContainerIndex;
};

View file

@ -4,7 +4,10 @@
#include "protocols/protocols_defs.h"
AwgConfigModel::AwgConfigModel(QObject *parent) : QAbstractListModel(parent)
AwgConfigModel::AwgConfigModel(QObject *parent)
: QAbstractListModel(parent),
m_newAwgProtocolConfig(ProtocolProps::protoToString(Proto::Awg)),
m_oldAwgProtocolConfig(ProtocolProps::protoToString(Proto::Awg))
{
}
@ -21,46 +24,42 @@ bool AwgConfigModel::setData(const QModelIndex &index, const QVariant &value, in
}
switch (role) {
case Roles::SubnetAddressRole: m_serverProtocolConfig.insert(config_key::subnet_address, value.toString()); break;
case Roles::PortRole: m_serverProtocolConfig.insert(config_key::port, value.toString()); break;
case Roles::SubnetAddressRole: m_newAwgProtocolConfig.serverProtocolConfig.subnetAddress = value.toString(); break;
case Roles::PortRole: m_newAwgProtocolConfig.serverProtocolConfig.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::ClientSpecialHandshakeTimeoutRole:
m_clientProtocolConfig.insert(config_key::specialHandshakeTimeout, value.toString());
case Roles::ClientMtuRole: m_newAwgProtocolConfig.clientProtocolConfig.wireGuardData.mtu = value.toString(); break;
case Roles::ClientJunkPacketCountRole: m_newAwgProtocolConfig.clientProtocolConfig.awgData.junkPacketCount = value.toString(); break;
case Roles::ClientJunkPacketMinSizeRole:
m_newAwgProtocolConfig.clientProtocolConfig.awgData.junkPacketMinSize = value.toString();
break;
case Roles::ClientJunkPacketMaxSizeRole:
m_newAwgProtocolConfig.clientProtocolConfig.awgData.junkPacketMaxSize = value.toString();
break;
case Roles::ServerJunkPacketCountRole: m_newAwgProtocolConfig.serverProtocolConfig.awgData.junkPacketCount = value.toString(); break;
case Roles::ServerJunkPacketMinSizeRole:
m_newAwgProtocolConfig.serverProtocolConfig.awgData.junkPacketMinSize = value.toString();
break;
case Roles::ServerJunkPacketMaxSizeRole:
m_newAwgProtocolConfig.serverProtocolConfig.awgData.junkPacketMaxSize = value.toString();
break;
case Roles::ServerInitPacketJunkSizeRole:
m_newAwgProtocolConfig.serverProtocolConfig.awgData.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());
m_newAwgProtocolConfig.serverProtocolConfig.awgData.responsePacketJunkSize = value.toString();
break;
case Roles::ServerInitPacketMagicHeaderRole:
m_newAwgProtocolConfig.serverProtocolConfig.awgData.initPacketMagicHeader = 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::ServerResponsePacketMagicHeaderRole:
m_serverProtocolConfig.insert(config_key::responsePacketMagicHeader, value.toString());
m_newAwgProtocolConfig.serverProtocolConfig.awgData.responsePacketMagicHeader = value.toString();
break;
case Roles::ServerUnderloadPacketMagicHeaderRole:
m_serverProtocolConfig.insert(config_key::underloadPacketMagicHeader, value.toString());
m_newAwgProtocolConfig.serverProtocolConfig.awgData.underloadPacketMagicHeader = value.toString();
break;
case Roles::ServerTransportPacketMagicHeaderRole:
m_serverProtocolConfig.insert(config_key::transportPacketMagicHeader, value.toString());
m_newAwgProtocolConfig.serverProtocolConfig.awgData.transportPacketMagicHeader = value.toString();
break;
}
@ -75,137 +74,42 @@ QVariant AwgConfigModel::data(const QModelIndex &index, int role) const
}
switch (role) {
case Roles::SubnetAddressRole: return m_serverProtocolConfig.value(config_key::subnet_address).toString();
case Roles::PortRole: return m_serverProtocolConfig.value(config_key::port).toString();
case Roles::SubnetAddressRole: return m_newAwgProtocolConfig.serverProtocolConfig.subnetAddress;
case Roles::PortRole: return m_newAwgProtocolConfig.serverProtocolConfig.port;
case Roles::ClientMtuRole: return m_clientProtocolConfig.value(config_key::mtu);
case Roles::ClientJunkPacketCountRole: return m_clientProtocolConfig.value(config_key::junkPacketCount);
case Roles::ClientJunkPacketMinSizeRole: return m_clientProtocolConfig.value(config_key::junkPacketMinSize);
case Roles::ClientJunkPacketMaxSizeRole: return m_clientProtocolConfig.value(config_key::junkPacketMaxSize);
case Roles::ClientSpecialJunk1Role: return m_clientProtocolConfig.value(config_key::specialJunk1);
case Roles::ClientSpecialJunk2Role: return m_clientProtocolConfig.value(config_key::specialJunk2);
case Roles::ClientSpecialJunk3Role: return m_clientProtocolConfig.value(config_key::specialJunk3);
case Roles::ClientSpecialJunk4Role: return m_clientProtocolConfig.value(config_key::specialJunk4);
case Roles::ClientSpecialJunk5Role: return m_clientProtocolConfig.value(config_key::specialJunk5);
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::ClientMtuRole: return m_newAwgProtocolConfig.clientProtocolConfig.wireGuardData.mtu;
case Roles::ClientJunkPacketCountRole: return m_newAwgProtocolConfig.clientProtocolConfig.awgData.junkPacketCount;
case Roles::ClientJunkPacketMinSizeRole: return m_newAwgProtocolConfig.clientProtocolConfig.awgData.junkPacketMinSize;
case Roles::ClientJunkPacketMaxSizeRole: return m_newAwgProtocolConfig.clientProtocolConfig.awgData.junkPacketMaxSize;
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::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::ServerJunkPacketCountRole: return m_newAwgProtocolConfig.serverProtocolConfig.awgData.junkPacketCount;
case Roles::ServerJunkPacketMinSizeRole: return m_newAwgProtocolConfig.serverProtocolConfig.awgData.junkPacketMinSize;
case Roles::ServerJunkPacketMaxSizeRole: return m_newAwgProtocolConfig.serverProtocolConfig.awgData.junkPacketMaxSize;
case Roles::ServerInitPacketJunkSizeRole: return m_newAwgProtocolConfig.serverProtocolConfig.awgData.initPacketJunkSize;
case Roles::ServerResponsePacketJunkSizeRole: return m_newAwgProtocolConfig.serverProtocolConfig.awgData.responsePacketJunkSize;
case Roles::ServerInitPacketMagicHeaderRole: return m_newAwgProtocolConfig.serverProtocolConfig.awgData.initPacketMagicHeader;
case Roles::ServerResponsePacketMagicHeaderRole: return m_newAwgProtocolConfig.serverProtocolConfig.awgData.responsePacketMagicHeader;
case Roles::ServerUnderloadPacketMagicHeaderRole: return m_newAwgProtocolConfig.serverProtocolConfig.awgData.underloadPacketMagicHeader;
case Roles::ServerTransportPacketMagicHeaderRole: return m_newAwgProtocolConfig.serverProtocolConfig.awgData.transportPacketMagicHeader;
}
return QVariant();
}
void AwgConfigModel::updateModel(const QJsonObject &config)
void AwgConfigModel::updateModel(const AwgProtocolConfig awgProtocolConfig)
{
beginResetModel();
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
m_fullConfig = config;
QJsonObject serverProtocolConfig = config.value(config_key::awg).toObject();
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::junkPacketCount] =
serverProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
m_serverProtocolConfig[config_key::junkPacketMinSize] =
serverProtocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize);
m_serverProtocolConfig[config_key::junkPacketMaxSize] =
serverProtocolConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize);
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);
m_serverProtocolConfig[config_key::initPacketMagicHeader] =
serverProtocolConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader);
m_serverProtocolConfig[config_key::responsePacketMagicHeader] =
serverProtocolConfig.value(config_key::responsePacketMagicHeader).toString(protocols::awg::defaultResponsePacketMagicHeader);
m_serverProtocolConfig[config_key::underloadPacketMagicHeader] =
serverProtocolConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader);
m_serverProtocolConfig[config_key::transportPacketMagicHeader] =
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());
m_clientProtocolConfig[config_key::junkPacketMinSize] =
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());
m_clientProtocolConfig[config_key::specialJunk1] =
clientProtocolConfig.value(config_key::specialJunk1).toString(protocols::awg::defaultSpecialJunk1);
m_clientProtocolConfig[config_key::specialJunk2] =
clientProtocolConfig.value(config_key::specialJunk2).toString(protocols::awg::defaultSpecialJunk2);
m_clientProtocolConfig[config_key::specialJunk3] =
clientProtocolConfig.value(config_key::specialJunk3).toString(protocols::awg::defaultSpecialJunk3);
m_clientProtocolConfig[config_key::specialJunk4] =
clientProtocolConfig.value(config_key::specialJunk4).toString(protocols::awg::defaultSpecialJunk4);
m_clientProtocolConfig[config_key::specialJunk5] =
clientProtocolConfig.value(config_key::specialJunk5).toString(protocols::awg::defaultSpecialJunk5);
m_clientProtocolConfig[config_key::controlledJunk1] =
clientProtocolConfig.value(config_key::controlledJunk1).toString(protocols::awg::defaultControlledJunk1);
m_clientProtocolConfig[config_key::controlledJunk2] =
clientProtocolConfig.value(config_key::controlledJunk2).toString(protocols::awg::defaultControlledJunk2);
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);
m_newAwgProtocolConfig = awgProtocolConfig;
m_oldAwgProtocolConfig = awgProtocolConfig;
endResetModel();
}
QJsonObject AwgConfigModel::getConfig()
QSharedPointer<ProtocolConfig> AwgConfigModel::getConfig()
{
const AwgConfig oldConfig(m_fullConfig.value(config_key::awg).toObject());
const AwgConfig newConfig(m_serverProtocolConfig);
if (!oldConfig.hasEqualServerSettings(newConfig)) {
m_serverProtocolConfig.remove(config_key::last_config);
} else {
auto lastConfig = m_serverProtocolConfig.value(config_key::last_config).toString();
QJsonObject jsonConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object();
jsonConfig[config_key::mtu] = m_clientProtocolConfig[config_key::mtu];
jsonConfig[config_key::junkPacketCount] = m_clientProtocolConfig[config_key::junkPacketCount];
jsonConfig[config_key::junkPacketMinSize] = m_clientProtocolConfig[config_key::junkPacketMinSize];
jsonConfig[config_key::junkPacketMaxSize] = m_clientProtocolConfig[config_key::junkPacketMaxSize];
jsonConfig[config_key::specialJunk1] = m_clientProtocolConfig[config_key::specialJunk1];
jsonConfig[config_key::specialJunk2] = m_clientProtocolConfig[config_key::specialJunk2];
jsonConfig[config_key::specialJunk3] = m_clientProtocolConfig[config_key::specialJunk3];
jsonConfig[config_key::specialJunk4] = m_clientProtocolConfig[config_key::specialJunk4];
jsonConfig[config_key::specialJunk5] = m_clientProtocolConfig[config_key::specialJunk5];
jsonConfig[config_key::controlledJunk1] = m_clientProtocolConfig[config_key::controlledJunk1];
jsonConfig[config_key::controlledJunk2] = m_clientProtocolConfig[config_key::controlledJunk2];
jsonConfig[config_key::controlledJunk3] = m_clientProtocolConfig[config_key::controlledJunk3];
jsonConfig[config_key::specialHandshakeTimeout] = m_clientProtocolConfig[config_key::specialHandshakeTimeout];
m_serverProtocolConfig[config_key::last_config] = QString(QJsonDocument(jsonConfig).toJson());
if (m_oldAwgProtocolConfig.hasEqualServerSettings(m_newAwgProtocolConfig)) {
m_newAwgProtocolConfig.clearClientSettings();
}
m_fullConfig.insert(config_key::awg, m_serverProtocolConfig);
return m_fullConfig;
return QSharedPointer<AwgProtocolConfig>::create(m_newAwgProtocolConfig);
}
bool AwgConfigModel::isHeadersEqual(const QString &h1, const QString &h2, const QString &h3, const QString &h4)
@ -215,26 +119,12 @@ bool AwgConfigModel::isHeadersEqual(const QString &h1, const QString &h2, const
bool AwgConfigModel::isPacketSizeEqual(const int s1, const int s2)
{
return (AwgConstant::messageInitiationSize + s1 == AwgConstant::messageResponseSize + s2);
return (awg::messageInitiationSize + s1 == awg::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());
const AwgConfig newConfig(m_serverProtocolConfig);
return oldConfig.hasEqualServerSettings(newConfig);
return m_oldAwgProtocolConfig.hasEqualServerSettings(m_newAwgProtocolConfig);
}
QHash<int, QByteArray> AwgConfigModel::roleNames() const
@ -248,24 +138,12 @@ QHash<int, QByteArray> AwgConfigModel::roleNames() const
roles[ClientJunkPacketCountRole] = "clientJunkPacketCount";
roles[ClientJunkPacketMinSizeRole] = "clientJunkPacketMinSize";
roles[ClientJunkPacketMaxSizeRole] = "clientJunkPacketMaxSize";
roles[ClientSpecialJunk1Role] = "clientSpecialJunk1";
roles[ClientSpecialJunk2Role] = "clientSpecialJunk2";
roles[ClientSpecialJunk3Role] = "clientSpecialJunk3";
roles[ClientSpecialJunk4Role] = "clientSpecialJunk4";
roles[ClientSpecialJunk5Role] = "clientSpecialJunk5";
roles[ClientControlledJunk1Role] = "clientControlledJunk1";
roles[ClientControlledJunk2Role] = "clientControlledJunk2";
roles[ClientControlledJunk3Role] = "clientControlledJunk3";
roles[ClientSpecialHandshakeTimeoutRole] = "clientSpecialHandshakeTimeout";
roles[ServerJunkPacketCountRole] = "serverJunkPacketCount";
roles[ServerJunkPacketMinSizeRole] = "serverJunkPacketMinSize";
roles[ServerJunkPacketMaxSizeRole] = "serverJunkPacketMaxSize";
roles[ServerInitPacketJunkSizeRole] = "serverInitPacketJunkSize";
roles[ServerResponsePacketJunkSizeRole] = "serverResponsePacketJunkSize";
roles[ServerCookieReplyPacketJunkSizeRole] = "serverCookieReplyPacketJunkSize";
roles[ServerTransportPacketJunkSizeRole] = "serverTransportPacketJunkSize";
roles[ServerInitPacketMagicHeaderRole] = "serverInitPacketMagicHeader";
roles[ServerResponsePacketMagicHeaderRole] = "serverResponsePacketMagicHeader";
roles[ServerUnderloadPacketMagicHeaderRole] = "serverUnderloadPacketMagicHeader";
@ -273,74 +151,3 @@ QHash<int, QByteArray> AwgConfigModel::roleNames() const
return roles;
}
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);
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);
}
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
|| serverInitPacketMagicHeader != other.serverInitPacketMagicHeader
|| serverResponsePacketMagicHeader != other.serverResponsePacketMagicHeader
|| serverUnderloadPacketMagicHeader != other.serverUnderloadPacketMagicHeader
|| serverTransportPacketMagicHeader != other.serverTransportPacketMagicHeader) {
return false;
}
return true;
}
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
|| clientSpecialHandshakeTimeout != other.clientSpecialHandshakeTimeout) {
return false;
}
return true;
}

View file

@ -5,51 +5,7 @@
#include <QJsonObject>
#include "containers/containers_defs.h"
namespace AwgConstant
{
const int messageInitiationSize = 148;
const int messageResponseSize = 92;
const int messageCookieReplySize = 64;
const int messageTransportSize = 32;
}
struct AwgConfig
{
AwgConfig(const QJsonObject &jsonConfig);
QString subnetAddress;
QString port;
QString clientMtu;
QString clientJunkPacketCount;
QString clientJunkPacketMinSize;
QString clientJunkPacketMaxSize;
QString clientSpecialJunk1;
QString clientSpecialJunk2;
QString clientSpecialJunk3;
QString clientSpecialJunk4;
QString clientSpecialJunk5;
QString clientControlledJunk1;
QString clientControlledJunk2;
QString clientControlledJunk3;
QString clientSpecialHandshakeTimeout;
QString serverJunkPacketCount;
QString serverJunkPacketMinSize;
QString serverJunkPacketMaxSize;
QString serverInitPacketJunkSize;
QString serverResponsePacketJunkSize;
QString serverCookieReplyPacketJunkSize;
QString serverTransportPacketJunkSize;
QString serverInitPacketMagicHeader;
QString serverResponsePacketMagicHeader;
QString serverUnderloadPacketMagicHeader;
QString serverTransportPacketMagicHeader;
bool hasEqualServerSettings(const AwgConfig &other) const;
bool hasEqualClientSettings(const AwgConfig &other) const;
};
#include "core/models/protocols/awgProtocolConfig.h"
class AwgConfigModel : public QAbstractListModel
{
@ -64,28 +20,16 @@ public:
ClientJunkPacketCountRole,
ClientJunkPacketMinSizeRole,
ClientJunkPacketMaxSizeRole,
ClientSpecialJunk1Role,
ClientSpecialJunk2Role,
ClientSpecialJunk3Role,
ClientSpecialJunk4Role,
ClientSpecialJunk5Role,
ClientControlledJunk1Role,
ClientControlledJunk2Role,
ClientControlledJunk3Role,
ClientSpecialHandshakeTimeoutRole,
ServerJunkPacketCountRole,
ServerJunkPacketMinSizeRole,
ServerJunkPacketMaxSizeRole,
ServerInitPacketJunkSizeRole,
ServerResponsePacketJunkSizeRole,
ServerCookieReplyPacketJunkSizeRole,
ServerTransportPacketJunkSizeRole,
ServerInitPacketMagicHeaderRole,
ServerResponsePacketMagicHeaderRole,
ServerUnderloadPacketMagicHeaderRole,
ServerTransportPacketMagicHeaderRole,
ServerTransportPacketMagicHeaderRole
};
explicit AwgConfigModel(QObject *parent = nullptr);
@ -96,11 +40,11 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
public slots:
void updateModel(const QJsonObject &config);
QJsonObject getConfig();
void updateModel(const AwgProtocolConfig awgProtocolConfig);
QSharedPointer<ProtocolConfig> 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();
@ -108,10 +52,8 @@ protected:
QHash<int, QByteArray> roleNames() const override;
private:
DockerContainer m_container;
QJsonObject m_serverProtocolConfig;
QJsonObject m_clientProtocolConfig;
QJsonObject m_fullConfig;
AwgProtocolConfig m_newAwgProtocolConfig;
AwgProtocolConfig m_oldAwgProtocolConfig;
};
#endif // AWGCONFIGMODEL_H

View file

@ -2,7 +2,10 @@
#include "protocols/protocols_defs.h"
CloakConfigModel::CloakConfigModel(QObject *parent) : QAbstractListModel(parent)
CloakConfigModel::CloakConfigModel(QObject *parent)
: QAbstractListModel(parent),
m_newCloakProtocolConfig(QJsonObject(), ProtocolProps::protoToString(Proto::Cloak)),
m_oldCloakProtocolConfig(QJsonObject(), ProtocolProps::protoToString(Proto::Cloak))
{
}
@ -19,9 +22,9 @@ bool CloakConfigModel::setData(const QModelIndex &index, const QVariant &value,
}
switch (role) {
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
case Roles::CipherRole: m_protocolConfig.insert(config_key::cipher, value.toString()); break;
case Roles::SiteRole: m_protocolConfig.insert(config_key::site, value.toString()); break;
case Roles::PortRole: m_newCloakProtocolConfig.serverProtocolConfig.port = value.toString(); break;
case Roles::CipherRole: m_newCloakProtocolConfig.serverProtocolConfig.cipher = value.toString(); break;
case Roles::SiteRole: m_newCloakProtocolConfig.serverProtocolConfig.site = value.toString(); break;
}
emit dataChanged(index, index, QList { role });
@ -35,35 +38,33 @@ QVariant CloakConfigModel::data(const QModelIndex &index, int role) const
}
switch (role) {
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::cloak::defaultPort);
case Roles::CipherRole: return m_protocolConfig.value(config_key::cipher).toString(protocols::cloak::defaultCipher);
case Roles::SiteRole: return m_protocolConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite);
case Roles::PortRole: return m_newCloakProtocolConfig.serverProtocolConfig.port;
case Roles::CipherRole: return m_newCloakProtocolConfig.serverProtocolConfig.cipher;
case Roles::SiteRole: return m_newCloakProtocolConfig.serverProtocolConfig.site;
}
return QVariant();
}
void CloakConfigModel::updateModel(const QJsonObject &config)
void CloakConfigModel::updateModel(const CloakProtocolConfig cloakProtocolConfig)
{
beginResetModel();
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
m_fullConfig = config;
QJsonObject protocolConfig = config.value(config_key::cloak).toObject();
auto defaultTransportProto = ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::Cloak), Proto::Cloak);
m_protocolConfig.insert(config_key::transport_proto, protocolConfig.value(config_key::transport_proto).toString(defaultTransportProto));
m_protocolConfig.insert(config_key::cipher, protocolConfig.value(config_key::cipher).toString(protocols::cloak::defaultCipher));
m_protocolConfig.insert(config_key::port, protocolConfig.value(config_key::port).toString(protocols::cloak::defaultPort));
m_protocolConfig.insert(config_key::site, protocolConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite));
m_newCloakProtocolConfig = cloakProtocolConfig;
m_oldCloakProtocolConfig = cloakProtocolConfig;
endResetModel();
}
QJsonObject CloakConfigModel::getConfig()
QSharedPointer<ProtocolConfig> CloakConfigModel::getConfig()
{
m_fullConfig.insert(config_key::cloak, m_protocolConfig);
return m_fullConfig;
if (m_oldCloakProtocolConfig.hasEqualServerSettings(m_newCloakProtocolConfig)) {
m_newCloakProtocolConfig.clearClientSettings();
}
return QSharedPointer<CloakProtocolConfig>::create(m_newCloakProtocolConfig);
}
bool CloakConfigModel::isServerSettingsEqual()
{
return m_oldCloakProtocolConfig.hasEqualServerSettings(m_newCloakProtocolConfig);
}
QHash<int, QByteArray> CloakConfigModel::roleNames() const
@ -76,3 +77,4 @@ QHash<int, QByteArray> CloakConfigModel::roleNames() const
return roles;
}

View file

@ -5,6 +5,7 @@
#include <QJsonObject>
#include "containers/containers_defs.h"
#include "core/models/protocols/cloakProtocolConfig.h"
class CloakConfigModel : public QAbstractListModel
{
@ -25,16 +26,17 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
public slots:
void updateModel(const QJsonObject &config);
QJsonObject getConfig();
void updateModel(const CloakProtocolConfig cloakProtocolConfig);
QSharedPointer<ProtocolConfig> getConfig();
bool isServerSettingsEqual();
protected:
QHash<int, QByteArray> roleNames() const override;
private:
DockerContainer m_container;
QJsonObject m_protocolConfig;
QJsonObject m_fullConfig;
CloakProtocolConfig m_newCloakProtocolConfig;
CloakProtocolConfig m_oldCloakProtocolConfig;
};
#endif // CLOAKCONFIGMODEL_H

View file

@ -2,7 +2,10 @@
#include "protocols/protocols_defs.h"
OpenVpnConfigModel::OpenVpnConfigModel(QObject *parent) : QAbstractListModel(parent)
OpenVpnConfigModel::OpenVpnConfigModel(QObject *parent)
: QAbstractListModel(parent),
m_newOpenVpnProtocolConfig(QJsonObject(), ProtocolProps::protoToString(Proto::OpenVpn)),
m_oldOpenVpnProtocolConfig(QJsonObject(), ProtocolProps::protoToString(Proto::OpenVpn))
{
}
@ -19,16 +22,16 @@ bool OpenVpnConfigModel::setData(const QModelIndex &index, const QVariant &value
}
switch (role) {
case Roles::SubnetAddressRole: m_protocolConfig.insert(amnezia::config_key::subnet_address, value.toString()); break;
case Roles::TransportProtoRole: m_protocolConfig.insert(config_key::transport_proto, value.toString()); break;
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
case Roles::AutoNegotiateEncryprionRole: m_protocolConfig.insert(config_key::ncp_disable, !value.toBool()); break;
case Roles::HashRole: m_protocolConfig.insert(config_key::hash, value.toString()); break;
case Roles::CipherRole: m_protocolConfig.insert(config_key::cipher, value.toString()); break;
case Roles::TlsAuthRole: m_protocolConfig.insert(config_key::tls_auth, value.toBool()); break;
case Roles::BlockDnsRole: m_protocolConfig.insert(config_key::block_outside_dns, value.toBool()); break;
case Roles::AdditionalClientCommandsRole: m_protocolConfig.insert(config_key::additional_client_config, value.toString()); break;
case Roles::AdditionalServerCommandsRole: m_protocolConfig.insert(config_key::additional_server_config, value.toString()); break;
case Roles::SubnetAddressRole: m_newOpenVpnProtocolConfig.serverProtocolConfig.subnetAddress = value.toString(); break;
case Roles::TransportProtoRole: m_newOpenVpnProtocolConfig.serverProtocolConfig.transportProto = value.toString(); break;
case Roles::PortRole: m_newOpenVpnProtocolConfig.serverProtocolConfig.port = value.toString(); break;
case Roles::AutoNegotiateEncryprionRole: m_newOpenVpnProtocolConfig.serverProtocolConfig.ncpDisable = !value.toBool(); break;
case Roles::HashRole: m_newOpenVpnProtocolConfig.serverProtocolConfig.hash = value.toString(); break;
case Roles::CipherRole: m_newOpenVpnProtocolConfig.serverProtocolConfig.cipher = value.toString(); break;
case Roles::TlsAuthRole: m_newOpenVpnProtocolConfig.serverProtocolConfig.tlsAuth = value.toBool(); break;
case Roles::BlockDnsRole: m_newOpenVpnProtocolConfig.serverProtocolConfig.blockOutsideDns = value.toBool(); break;
case Roles::AdditionalClientCommandsRole: m_newOpenVpnProtocolConfig.serverProtocolConfig.additionalClientConfig = value.toString(); break;
case Roles::AdditionalServerCommandsRole: m_newOpenVpnProtocolConfig.serverProtocolConfig.additionalServerConfig = value.toString(); break;
}
emit dataChanged(index, index, QList { role });
@ -42,72 +45,42 @@ QVariant OpenVpnConfigModel::data(const QModelIndex &index, int role) const
}
switch (role) {
case Roles::SubnetAddressRole:
return m_protocolConfig.value(amnezia::config_key::subnet_address).toString(amnezia::protocols::openvpn::defaultSubnetAddress);
case Roles::TransportProtoRole:
return m_protocolConfig.value(config_key::transport_proto).toString(protocols::openvpn::defaultTransportProto);
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::openvpn::defaultPort);
case Roles::AutoNegotiateEncryprionRole:
return !m_protocolConfig.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable);
case Roles::HashRole: return m_protocolConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash);
case Roles::CipherRole: return m_protocolConfig.value(config_key::cipher).toString(protocols::openvpn::defaultCipher);
case Roles::TlsAuthRole: return m_protocolConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth);
case Roles::BlockDnsRole:
return m_protocolConfig.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns);
case Roles::AdditionalClientCommandsRole:
return m_protocolConfig.value(config_key::additional_client_config).toString(protocols::openvpn::defaultAdditionalClientConfig);
case Roles::AdditionalServerCommandsRole:
return m_protocolConfig.value(config_key::additional_server_config).toString(protocols::openvpn::defaultAdditionalServerConfig);
case Roles::IsPortEditable: return m_container == DockerContainer::OpenVpn ? true : false;
case Roles::IsTransportProtoEditable: return m_container == DockerContainer::OpenVpn ? true : false;
case Roles::HasRemoveButton: return m_container == DockerContainer::OpenVpn ? true : false;
case Roles::SubnetAddressRole: return m_newOpenVpnProtocolConfig.serverProtocolConfig.subnetAddress;
case Roles::TransportProtoRole: return m_newOpenVpnProtocolConfig.serverProtocolConfig.transportProto;
case Roles::PortRole: return m_newOpenVpnProtocolConfig.serverProtocolConfig.port;
case Roles::AutoNegotiateEncryprionRole: return !m_newOpenVpnProtocolConfig.serverProtocolConfig.ncpDisable;
case Roles::HashRole: return m_newOpenVpnProtocolConfig.serverProtocolConfig.hash;
case Roles::CipherRole: return m_newOpenVpnProtocolConfig.serverProtocolConfig.cipher;
case Roles::TlsAuthRole: return m_newOpenVpnProtocolConfig.serverProtocolConfig.tlsAuth;
case Roles::BlockDnsRole: return m_newOpenVpnProtocolConfig.serverProtocolConfig.blockOutsideDns;
case Roles::AdditionalClientCommandsRole: return m_newOpenVpnProtocolConfig.serverProtocolConfig.additionalClientConfig;
case Roles::AdditionalServerCommandsRole: return m_newOpenVpnProtocolConfig.serverProtocolConfig.additionalServerConfig;
case Roles::IsPortEditable: return true; // TODO: implement container check if needed
case Roles::IsTransportProtoEditable: return true; // TODO: implement container check if needed
case Roles::HasRemoveButton: return true; // TODO: implement container check if needed
}
return QVariant();
}
void OpenVpnConfigModel::updateModel(const QJsonObject &config)
void OpenVpnConfigModel::updateModel(const OpenVpnProtocolConfig openVpnProtocolConfig)
{
beginResetModel();
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
m_fullConfig = config;
QJsonObject protocolConfig = config.value(config_key::openvpn).toObject();
m_protocolConfig.insert(
config_key::subnet_address,
protocolConfig.value(amnezia::config_key::subnet_address).toString(amnezia::protocols::openvpn::defaultSubnetAddress));
QString transportProto;
if (m_container == DockerContainer::OpenVpn) {
transportProto = protocolConfig.value(config_key::transport_proto).toString(protocols::openvpn::defaultTransportProto);
} else {
transportProto = "tcp";
}
m_protocolConfig.insert(config_key::transport_proto, transportProto);
m_protocolConfig.insert(config_key::ncp_disable,
protocolConfig.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable));
m_protocolConfig.insert(config_key::cipher, protocolConfig.value(config_key::cipher).toString(protocols::openvpn::defaultCipher));
m_protocolConfig.insert(config_key::hash, protocolConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash));
m_protocolConfig.insert(config_key::block_outside_dns,
protocolConfig.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns));
m_protocolConfig.insert(config_key::port, protocolConfig.value(config_key::port).toString(protocols::openvpn::defaultPort));
m_protocolConfig.insert(config_key::tls_auth, protocolConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth));
m_protocolConfig.insert(
config_key::additional_client_config,
protocolConfig.value(config_key::additional_client_config).toString(protocols::openvpn::defaultAdditionalClientConfig));
m_protocolConfig.insert(
config_key::additional_server_config,
protocolConfig.value(config_key::additional_server_config).toString(protocols::openvpn::defaultAdditionalServerConfig));
m_newOpenVpnProtocolConfig = openVpnProtocolConfig;
m_oldOpenVpnProtocolConfig = openVpnProtocolConfig;
endResetModel();
}
QJsonObject OpenVpnConfigModel::getConfig()
QSharedPointer<ProtocolConfig> OpenVpnConfigModel::getConfig()
{
m_fullConfig.insert(config_key::openvpn, m_protocolConfig);
return m_fullConfig;
if (m_oldOpenVpnProtocolConfig.hasEqualServerSettings(m_newOpenVpnProtocolConfig)) {
m_newOpenVpnProtocolConfig.clearClientSettings();
}
return QSharedPointer<OpenVpnProtocolConfig>::create(m_newOpenVpnProtocolConfig);
}
bool OpenVpnConfigModel::isServerSettingsEqual()
{
return m_oldOpenVpnProtocolConfig.hasEqualServerSettings(m_newOpenVpnProtocolConfig);
}
QHash<int, QByteArray> OpenVpnConfigModel::roleNames() const

View file

@ -5,6 +5,7 @@
#include <QJsonObject>
#include "containers/containers_defs.h"
#include "core/models/protocols/openvpnProtocolConfig.h"
class OpenVpnConfigModel : public QAbstractListModel
{
@ -37,16 +38,17 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
public slots:
void updateModel(const QJsonObject &config);
QJsonObject getConfig();
void updateModel(const OpenVpnProtocolConfig openVpnProtocolConfig);
QSharedPointer<ProtocolConfig> getConfig();
bool isServerSettingsEqual();
protected:
QHash<int, QByteArray> roleNames() const override;
private:
DockerContainer m_container;
QJsonObject m_protocolConfig;
QJsonObject m_fullConfig;
OpenVpnProtocolConfig m_newOpenVpnProtocolConfig;
OpenVpnProtocolConfig m_oldOpenVpnProtocolConfig;
};
#endif // OPENVPNCONFIGMODEL_H

View file

@ -2,7 +2,10 @@
#include "protocols/protocols_defs.h"
ShadowSocksConfigModel::ShadowSocksConfigModel(QObject *parent) : QAbstractListModel(parent)
ShadowSocksConfigModel::ShadowSocksConfigModel(QObject *parent)
: QAbstractListModel(parent),
m_newShadowsocksProtocolConfig(QJsonObject(), ProtocolProps::protoToString(Proto::ShadowSocks)),
m_oldShadowsocksProtocolConfig(QJsonObject(), ProtocolProps::protoToString(Proto::ShadowSocks))
{
}
@ -19,8 +22,8 @@ bool ShadowSocksConfigModel::setData(const QModelIndex &index, const QVariant &v
}
switch (role) {
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
case Roles::CipherRole: m_protocolConfig.insert(config_key::cipher, value.toString()); break;
case Roles::PortRole: m_newShadowsocksProtocolConfig.serverProtocolConfig.port = value.toString(); break;
case Roles::CipherRole: m_newShadowsocksProtocolConfig.serverProtocolConfig.cipher = value.toString(); break;
}
emit dataChanged(index, index, QList { role });
@ -34,36 +37,34 @@ QVariant ShadowSocksConfigModel::data(const QModelIndex &index, int role) const
}
switch (role) {
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort);
case Roles::CipherRole: return m_protocolConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher);
case Roles::IsPortEditableRole: return m_container == DockerContainer::ShadowSocks ? true : false;
case Roles::IsCipherEditableRole: return m_container == DockerContainer::ShadowSocks ? true : false;
case Roles::PortRole: return m_newShadowsocksProtocolConfig.serverProtocolConfig.port;
case Roles::CipherRole: return m_newShadowsocksProtocolConfig.serverProtocolConfig.cipher;
case Roles::IsPortEditableRole: return true; // TODO: implement container check if needed
case Roles::IsCipherEditableRole: return true; // TODO: implement container check if needed
}
return QVariant();
}
void ShadowSocksConfigModel::updateModel(const QJsonObject &config)
void ShadowSocksConfigModel::updateModel(const ShadowsocksProtocolConfig shadowsocksProtocolConfig)
{
beginResetModel();
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
m_fullConfig = config;
QJsonObject protocolConfig = config.value(config_key::shadowsocks).toObject();
auto defaultTransportProto = ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::ShadowSocks), Proto::ShadowSocks);
m_protocolConfig.insert(config_key::transport_proto,
protocolConfig.value(config_key::transport_proto).toString(defaultTransportProto));
m_protocolConfig.insert(config_key::cipher, protocolConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher));
m_protocolConfig.insert(config_key::port, protocolConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort));
m_newShadowsocksProtocolConfig = shadowsocksProtocolConfig;
m_oldShadowsocksProtocolConfig = shadowsocksProtocolConfig;
endResetModel();
}
QJsonObject ShadowSocksConfigModel::getConfig()
QSharedPointer<ProtocolConfig> ShadowSocksConfigModel::getConfig()
{
m_fullConfig.insert(config_key::shadowsocks, m_protocolConfig);
return m_fullConfig;
if (m_oldShadowsocksProtocolConfig.hasEqualServerSettings(m_newShadowsocksProtocolConfig)) {
m_newShadowsocksProtocolConfig.clearClientSettings();
}
return QSharedPointer<ShadowsocksProtocolConfig>::create(m_newShadowsocksProtocolConfig);
}
bool ShadowSocksConfigModel::isServerSettingsEqual()
{
return m_oldShadowsocksProtocolConfig.hasEqualServerSettings(m_newShadowsocksProtocolConfig);
}
QHash<int, QByteArray> ShadowSocksConfigModel::roleNames() const
@ -77,3 +78,4 @@ QHash<int, QByteArray> ShadowSocksConfigModel::roleNames() const
return roles;
}

View file

@ -5,6 +5,7 @@
#include <QJsonObject>
#include "containers/containers_defs.h"
#include "core/models/protocols/shadowsocksProtocolConfig.h"
class ShadowSocksConfigModel : public QAbstractListModel
{
@ -26,16 +27,17 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
public slots:
void updateModel(const QJsonObject &config);
QJsonObject getConfig();
void updateModel(const ShadowsocksProtocolConfig shadowsocksProtocolConfig);
QSharedPointer<ProtocolConfig> getConfig();
bool isServerSettingsEqual();
protected:
QHash<int, QByteArray> roleNames() const override;
private:
DockerContainer m_container;
QJsonObject m_protocolConfig;
QJsonObject m_fullConfig;
ShadowsocksProtocolConfig m_newShadowsocksProtocolConfig;
ShadowsocksProtocolConfig m_oldShadowsocksProtocolConfig;
};
#endif // SHADOWSOCKSCONFIGMODEL_H

View file

@ -4,7 +4,10 @@
#include "protocols/protocols_defs.h"
WireGuardConfigModel::WireGuardConfigModel(QObject *parent) : QAbstractListModel(parent)
WireGuardConfigModel::WireGuardConfigModel(QObject *parent)
: QAbstractListModel(parent),
m_newWireGuardProtocolConfig(QJsonObject(), ProtocolProps::protoToString(Proto::WireGuard)),
m_oldWireGuardProtocolConfig(QJsonObject(), ProtocolProps::protoToString(Proto::WireGuard))
{
}
@ -21,9 +24,9 @@ bool WireGuardConfigModel::setData(const QModelIndex &index, const QVariant &val
}
switch (role) {
case Roles::SubnetAddressRole: m_serverProtocolConfig.insert(config_key::subnet_address, value.toString()); break;
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::SubnetAddressRole: m_newWireGuardProtocolConfig.serverProtocolConfig.subnetAddress = value.toString(); break;
case Roles::PortRole: m_newWireGuardProtocolConfig.serverProtocolConfig.port = value.toString(); break;
case Roles::ClientMtuRole: m_newWireGuardProtocolConfig.clientProtocolConfig.wireGuardData.mtu = value.toString(); break;
}
emit dataChanged(index, index, QList { role });
@ -37,62 +40,33 @@ QVariant WireGuardConfigModel::data(const QModelIndex &index, int role) const
}
switch (role) {
case Roles::SubnetAddressRole: return m_serverProtocolConfig.value(config_key::subnet_address).toString();
case Roles::PortRole: return m_serverProtocolConfig.value(config_key::port).toString();
case Roles::ClientMtuRole: return m_clientProtocolConfig.value(config_key::mtu);
case Roles::SubnetAddressRole: return m_newWireGuardProtocolConfig.serverProtocolConfig.subnetAddress;
case Roles::PortRole: return m_newWireGuardProtocolConfig.serverProtocolConfig.port;
case Roles::ClientMtuRole: return m_newWireGuardProtocolConfig.clientProtocolConfig.wireGuardData.mtu;
}
return QVariant();
}
void WireGuardConfigModel::updateModel(const QJsonObject &config)
void WireGuardConfigModel::updateModel(const WireGuardProtocolConfig wireGuardProtocolConfig)
{
beginResetModel();
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
m_fullConfig = config;
QJsonObject serverProtocolConfig = config.value(config_key::wireguard).toObject();
auto defaultTransportProto =
ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::WireGuard), Proto::WireGuard);
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::wireguard::defaultPort);
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::wireguard::defaultMtu);
m_newWireGuardProtocolConfig = wireGuardProtocolConfig;
m_oldWireGuardProtocolConfig = wireGuardProtocolConfig;
endResetModel();
}
QJsonObject WireGuardConfigModel::getConfig()
QSharedPointer<ProtocolConfig> WireGuardConfigModel::getConfig()
{
const WgConfig oldConfig(m_fullConfig.value(config_key::wireguard).toObject());
const WgConfig newConfig(m_serverProtocolConfig);
if (!oldConfig.hasEqualServerSettings(newConfig)) {
m_serverProtocolConfig.remove(config_key::last_config);
} else {
auto lastConfig = m_serverProtocolConfig.value(config_key::last_config).toString();
QJsonObject jsonConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object();
jsonConfig[config_key::mtu] = m_clientProtocolConfig[config_key::mtu];
m_serverProtocolConfig[config_key::last_config] = QString(QJsonDocument(jsonConfig).toJson());
if (m_oldWireGuardProtocolConfig.hasEqualServerSettings(m_newWireGuardProtocolConfig)) {
m_newWireGuardProtocolConfig.clearClientSettings();
}
m_fullConfig.insert(config_key::wireguard, m_serverProtocolConfig);
return m_fullConfig;
return QSharedPointer<WireGuardProtocolConfig>::create(m_newWireGuardProtocolConfig);
}
bool WireGuardConfigModel::isServerSettingsEqual()
{
const WgConfig oldConfig(m_fullConfig.value(config_key::wireguard).toObject());
const WgConfig newConfig(m_serverProtocolConfig);
return oldConfig.hasEqualServerSettings(newConfig);
return m_oldWireGuardProtocolConfig.hasEqualServerSettings(m_newWireGuardProtocolConfig);
}
QHash<int, QByteArray> WireGuardConfigModel::roleNames() const
@ -105,29 +79,3 @@ QHash<int, QByteArray> WireGuardConfigModel::roleNames() const
return roles;
}
WgConfig::WgConfig(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::wireguard::defaultMtu);
subnetAddress = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
port = serverProtocolConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
}
bool WgConfig::hasEqualServerSettings(const WgConfig &other) const
{
if (subnetAddress != other.subnetAddress || port != other.port) {
return false;
}
return true;
}
bool WgConfig::hasEqualClientSettings(const WgConfig &other) const
{
if (clientMtu != other.clientMtu) {
return false;
}
return true;
}

View file

@ -5,19 +5,7 @@
#include <QJsonObject>
#include "containers/containers_defs.h"
struct WgConfig
{
WgConfig(const QJsonObject &jsonConfig);
QString subnetAddress;
QString port;
QString clientMtu;
bool hasEqualServerSettings(const WgConfig &other) const;
bool hasEqualClientSettings(const WgConfig &other) const;
};
#include "core/models/protocols/wireguardProtocolConfig.h"
class WireGuardConfigModel : public QAbstractListModel
{
@ -38,8 +26,8 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
public slots:
void updateModel(const QJsonObject &config);
QJsonObject getConfig();
void updateModel(const WireGuardProtocolConfig wireGuardProtocolConfig);
QSharedPointer<ProtocolConfig> getConfig();
bool isServerSettingsEqual();
@ -47,10 +35,8 @@ protected:
QHash<int, QByteArray> roleNames() const override;
private:
DockerContainer m_container;
QJsonObject m_serverProtocolConfig;
QJsonObject m_clientProtocolConfig;
QJsonObject m_fullConfig;
WireGuardProtocolConfig m_newWireGuardProtocolConfig;
WireGuardProtocolConfig m_oldWireGuardProtocolConfig;
};
#endif // WIREGUARDCONFIGMODEL_H

View file

@ -2,7 +2,10 @@
#include "protocols/protocols_defs.h"
XrayConfigModel::XrayConfigModel(QObject *parent) : QAbstractListModel(parent)
XrayConfigModel::XrayConfigModel(QObject *parent)
: QAbstractListModel(parent),
m_newXrayProtocolConfig(QJsonObject(), ProtocolProps::protoToString(Proto::Xray)),
m_oldXrayProtocolConfig(QJsonObject(), ProtocolProps::protoToString(Proto::Xray))
{
}
@ -19,8 +22,8 @@ bool XrayConfigModel::setData(const QModelIndex &index, const QVariant &value, i
}
switch (role) {
case Roles::SiteRole: m_protocolConfig.insert(config_key::site, value.toString()); break;
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
case Roles::SiteRole: m_newXrayProtocolConfig.serverProtocolConfig.site = value.toString(); break;
case Roles::PortRole: m_newXrayProtocolConfig.serverProtocolConfig.port = value.toString(); break;
}
emit dataChanged(index, index, QList { role });
@ -34,34 +37,32 @@ QVariant XrayConfigModel::data(const QModelIndex &index, int role) const
}
switch (role) {
case Roles::SiteRole: return m_protocolConfig.value(config_key::site).toString(protocols::xray::defaultSite);
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::xray::defaultPort);
case Roles::SiteRole: return m_newXrayProtocolConfig.serverProtocolConfig.site;
case Roles::PortRole: return m_newXrayProtocolConfig.serverProtocolConfig.port;
}
return QVariant();
}
void XrayConfigModel::updateModel(const QJsonObject &config)
void XrayConfigModel::updateModel(const XrayProtocolConfig xrayProtocolConfig)
{
beginResetModel();
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
m_fullConfig = config;
QJsonObject protocolConfig = config.value(config_key::xray).toObject();
auto defaultTransportProto = ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::Xray), Proto::Xray);
m_protocolConfig.insert(config_key::transport_proto,
protocolConfig.value(config_key::transport_proto).toString(defaultTransportProto));
m_protocolConfig.insert(config_key::port, protocolConfig.value(config_key::port).toString(protocols::xray::defaultPort));
m_protocolConfig.insert(config_key::site, protocolConfig.value(config_key::site).toString(protocols::xray::defaultSite));
m_newXrayProtocolConfig = xrayProtocolConfig;
m_oldXrayProtocolConfig = xrayProtocolConfig;
endResetModel();
}
QJsonObject XrayConfigModel::getConfig()
QSharedPointer<ProtocolConfig> XrayConfigModel::getConfig()
{
m_fullConfig.insert(config_key::xray, m_protocolConfig);
return m_fullConfig;
if (m_oldXrayProtocolConfig.hasEqualServerSettings(m_newXrayProtocolConfig)) {
m_newXrayProtocolConfig.clearClientSettings();
}
return QSharedPointer<XrayProtocolConfig>::create(m_newXrayProtocolConfig);
}
bool XrayConfigModel::isServerSettingsEqual()
{
return m_oldXrayProtocolConfig.hasEqualServerSettings(m_newXrayProtocolConfig);
}
QHash<int, QByteArray> XrayConfigModel::roleNames() const
@ -73,3 +74,4 @@ QHash<int, QByteArray> XrayConfigModel::roleNames() const
return roles;
}

View file

@ -5,6 +5,7 @@
#include <QJsonObject>
#include "containers/containers_defs.h"
#include "core/models/protocols/xrayProtocolConfig.h"
class XrayConfigModel : public QAbstractListModel
{
@ -24,16 +25,17 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
public slots:
void updateModel(const QJsonObject &config);
QJsonObject getConfig();
void updateModel(const XrayProtocolConfig xrayProtocolConfig);
QSharedPointer<ProtocolConfig> getConfig();
bool isServerSettingsEqual();
protected:
QHash<int, QByteArray> roleNames() const override;
private:
DockerContainer m_container;
QJsonObject m_protocolConfig;
QJsonObject m_fullConfig;
XrayProtocolConfig m_newXrayProtocolConfig;
XrayProtocolConfig m_oldXrayProtocolConfig;
};
#endif // XRAYCONFIGMODEL_H

View file

@ -1,14 +1,45 @@
#include "protocols_model.h"
ProtocolsModel::ProtocolsModel(std::shared_ptr<Settings> settings, QObject *parent)
: m_settings(settings), QAbstractListModel(parent)
#include "core/models/protocols/awgProtocolConfig.h"
#include "core/models/protocols/cloakProtocolConfig.h"
#include "core/models/protocols/openvpnProtocolConfig.h"
#include "core/models/protocols/shadowsocksProtocolConfig.h"
#include "core/models/protocols/wireguardProtocolConfig.h"
#include "core/models/protocols/xrayProtocolConfig.h"
ProtocolsModel::ProtocolsModel(QObject *parent) : QAbstractListModel(parent)
{
}
ProtocolsModel::ProtocolsModel(const QSharedPointer<OpenVpnConfigModel> &openVpnConfigModel,
const QSharedPointer<ShadowSocksConfigModel> &shadowSocksConfigModel,
const QSharedPointer<CloakConfigModel> &cloakConfigModel,
const QSharedPointer<WireGuardConfigModel> &wireGuardConfigModel,
const QSharedPointer<AwgConfigModel> &awgConfigModel, const QSharedPointer<XrayConfigModel> &xrayConfigModel,
#ifdef Q_OS_WINDOWS
const QSharedPointer<Ikev2ConfigModel> &ikev2ConfigModel,
#endif
const QSharedPointer<SftpConfigModel> &sftpConfigModel,
const QSharedPointer<Socks5ProxyConfigModel> &socks5ProxyConfigModel, QObject *parent)
: QAbstractListModel(parent),
m_openVpnConfigModel(openVpnConfigModel),
m_shadowSocksConfigModel(shadowSocksConfigModel),
m_cloakConfigModel(cloakConfigModel),
m_wireGuardConfigModel(wireGuardConfigModel),
m_awgConfigModel(awgConfigModel),
m_xrayConfigModel(xrayConfigModel),
#ifdef Q_OS_WINDOWS
m_ikev2ConfigModel(ikev2ConfigModel),
#endif
m_sftpConfigModel(sftpConfigModel),
m_socks5ProxyConfigModel(socks5ProxyConfigModel)
{
}
int ProtocolsModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_content.size();
return m_protocolConfigs.size();
}
QHash<int, QByteArray> ProtocolsModel::roleNames() const
@ -27,60 +58,102 @@ QHash<int, QByteArray> ProtocolsModel::roleNames() const
QVariant ProtocolsModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= m_content.size()) {
if (!index.isValid() || index.row() < 0 || index.row() >= m_protocolConfigs.size()) {
return QVariant();
}
auto protocolConfig = m_protocolConfigs.at(index.row());
amnezia::Proto protocol = ProtocolProps::protoFromString(protocolConfig->protocolName);
switch (role) {
case ProtocolNameRole: {
amnezia::Proto proto = ProtocolProps::protoFromString(m_content.keys().at(index.row()));
return ProtocolProps::protocolHumanNames().value(proto);
return ProtocolProps::protocolHumanNames().value(protocol);
}
case ServerProtocolPageRole:
return static_cast<int>(serverProtocolPage(ProtocolProps::protoFromString(m_content.keys().at(index.row()))));
case ClientProtocolPageRole:
return static_cast<int>(clientProtocolPage(ProtocolProps::protoFromString(m_content.keys().at(index.row()))));
case ProtocolIndexRole: return ProtocolProps::protoFromString(m_content.keys().at(index.row()));
case RawConfigRole: {
auto protocolConfig = m_content.value(ContainerProps::containerTypeToString(m_container)).toObject();
auto lastConfigJsonDoc =
QJsonDocument::fromJson(protocolConfig.value(config_key::last_config).toString().toUtf8());
auto lastConfigJson = lastConfigJsonDoc.object();
case ServerProtocolPageRole: return static_cast<int>(serverProtocolPage(protocol));
case ClientProtocolPageRole: return static_cast<int>(clientProtocolPage(protocol));
case ProtocolIndexRole: return protocol;
// case RawConfigRole: {
// auto protocolConfig = m_content.value(ContainerProps::containerTypeToString(m_container)).toObject();
// auto lastConfigJsonDoc = QJsonDocument::fromJson(protocolConfig.value(config_key::last_config).toString().toUtf8());
// auto lastConfigJson = lastConfigJsonDoc.object();
QString rawConfig;
QStringList lines = lastConfigJson.value(config_key::config).toString().replace("\r", "").split("\n");
for (const QString &l : lines) {
rawConfig.append(l + "\n");
}
return rawConfig;
}
// QString rawConfig;
// QStringList lines = lastConfigJson.value(config_key::config).toString().replace("\r", "").split("\n");
// for (const QString &l : lines) {
// rawConfig.append(l + "\n");
// }
// return rawConfig;
// }
case IsClientProtocolExistsRole: {
auto protocolConfig = m_content.value(ContainerProps::containerTypeToString(m_container)).toObject();
auto lastConfigJsonDoc =
QJsonDocument::fromJson(protocolConfig.value(config_key::last_config).toString().toUtf8());
auto lastConfigJson = lastConfigJsonDoc.object();
auto configString = lastConfigJson.value(config_key::config).toString();
return !configString.isEmpty();
auto protocolVariant = ProtocolConfig::getProtocolConfigVariant(protocolConfig);
return std::visit([](const auto &ptr) -> bool { return ptr->clientProtocolConfig.isEmpty; }, protocolVariant);
}
}
return QVariant();
}
void ProtocolsModel::updateModel(const QJsonObject &content)
void ProtocolsModel::updateModel(const QMap<QString, QSharedPointer<ProtocolConfig>> &protocolConfigs)
{
m_container = ContainerProps::containerFromString(content.value(config_key::container).toString());
m_content = content;
m_content.remove(config_key::container);
beginResetModel();
m_protocolConfigs.clear();
for (const auto &protocolConfig : protocolConfigs) {
m_protocolConfigs.push_back(protocolConfig);
}
endResetModel();
}
QJsonObject ProtocolsModel::getConfig()
void ProtocolsModel::updateProtocolModel(amnezia::Proto protocol)
{
QJsonObject config = m_content;
config.insert(config_key::container, ContainerProps::containerToString(m_container));
return config;
QSharedPointer<ProtocolConfig> protocolConfig;
for (const auto &config : m_protocolConfigs) {
if (ProtocolProps::protoFromString(config->protocolName) == protocol) {
protocolConfig = config;
break;
}
}
switch (protocol) {
case Proto::OpenVpn: m_openVpnConfigModel->updateModel(*qSharedPointerCast<OpenVpnProtocolConfig>(protocolConfig).data()); break;
case Proto::ShadowSocks: m_shadowSocksConfigModel->updateModel(*qSharedPointerCast<ShadowsocksProtocolConfig>(protocolConfig).data()); break;
case Proto::Cloak: m_cloakConfigModel->updateModel(*qSharedPointerCast<CloakProtocolConfig>(protocolConfig).data()); break;
case Proto::WireGuard: m_wireGuardConfigModel->updateModel(*qSharedPointerCast<WireGuardProtocolConfig>(protocolConfig).data()); break;
case Proto::Awg: m_awgConfigModel->updateModel(*qSharedPointerCast<AwgProtocolConfig>(protocolConfig).data()); break;
case Proto::Xray: m_xrayConfigModel->updateModel(*qSharedPointerCast<XrayProtocolConfig>(protocolConfig).data()); break;
#ifdef Q_OS_WINDOWS
case Proto::Ikev2:
case Proto::L2tp: m_ikev2ConfigModel->updateModel(*qSharedPointerCast<AwgProtocolConfig>(protocolConfig).data()); break;
#endif
// case Proto::Sftp: m_sftpConfigModel->updateModel(*qSharedPointerCast<SftpConfigModel>(protocolConfig).data()); break;
// case Proto::Socks5Proxy: m_socks5ProxyConfigModel->updateModel(*qSharedPointerCast<Socks>(protocolConfig).data()); break;
default: break;
}
}
QMap<QString, QSharedPointer<ProtocolConfig>> ProtocolsModel::getProtocolConfigs()
{
QMap<QString, QSharedPointer<ProtocolConfig>> protocolConfigs;
for (const auto &config : m_protocolConfigs) {
switch (ProtocolProps::protoFromString(config->protocolName)) {
case Proto::OpenVpn: protocolConfigs.insert(config->protocolName, m_openVpnConfigModel->getConfig()); break;
case Proto::ShadowSocks: protocolConfigs.insert(config->protocolName, m_shadowSocksConfigModel->getConfig()); break;
case Proto::Cloak: protocolConfigs.insert(config->protocolName, m_cloakConfigModel->getConfig()); break;
case Proto::WireGuard: protocolConfigs.insert(config->protocolName, m_wireGuardConfigModel->getConfig()); break;
case Proto::Awg: protocolConfigs.insert(config->protocolName, m_awgConfigModel->getConfig()); break;
case Proto::Xray: protocolConfigs.insert(config->protocolName, m_xrayConfigModel->getConfig()); break;
#ifdef Q_OS_WINDOWS
case Proto::Ikev2:
case Proto::L2tp: protocolConfigs.insert(config->protocolName, m_awgConfigModel->getConfig()); break;
#endif
// case Proto::Sftp: protocolConfigs.insert(config->protocolName, m_awgConfigModel->getConfig()); break;
// case Proto::Socks5Proxy: protocolConfigs.insert(config->protocolName, m_awgConfigModel->getConfig()); break;
default: break;
}
}
return protocolConfigs;
}
PageLoader::PageEnum ProtocolsModel::serverProtocolPage(Proto protocol) const
@ -94,7 +167,7 @@ PageLoader::PageEnum ProtocolsModel::serverProtocolPage(Proto protocol) const
case Proto::Ikev2: return PageLoader::PageEnum::PageProtocolIKev2Settings;
case Proto::L2tp: return PageLoader::PageEnum::PageProtocolIKev2Settings;
case Proto::Xray: return PageLoader::PageEnum::PageProtocolXraySettings;
// non-vpn
case Proto::TorWebSite: return PageLoader::PageEnum::PageServiceTorWebsiteSettings;
case Proto::Dns: return PageLoader::PageEnum::PageServiceDnsSettings;

View file

@ -4,8 +4,19 @@
#include <QAbstractListModel>
#include <QJsonObject>
#include "../controllers/pageController.h"
#include "settings.h"
#include "core/models/protocols/protocolConfig.h"
#include "ui/controllers/pageController.h"
#include "ui/models/protocols/awgConfigModel.h"
#include "ui/models/protocols/cloakConfigModel.h"
#include "ui/models/protocols/openvpnConfigModel.h"
#include "ui/models/protocols/shadowsocksConfigModel.h"
#include "ui/models/protocols/wireguardConfigModel.h"
#include "ui/models/protocols/xrayConfigModel.h"
#ifdef Q_OS_WINDOWS
#include "ui/models/protocols/ikev2ConfigModel.h"
#endif
#include "ui/models/services/sftpConfigModel.h"
#include "ui/models/services/socks5ProxyConfigModel.h"
class ProtocolsModel : public QAbstractListModel
{
@ -20,16 +31,26 @@ public:
IsClientProtocolExistsRole
};
ProtocolsModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
ProtocolsModel(QObject *parent = nullptr);
ProtocolsModel(const QSharedPointer<OpenVpnConfigModel> &openVpnConfigModel,
const QSharedPointer<ShadowSocksConfigModel> &shadowSocksConfigModel,
const QSharedPointer<CloakConfigModel> &cloakConfigModel, const QSharedPointer<WireGuardConfigModel> &wireGuardConfigModel,
const QSharedPointer<AwgConfigModel> &awgConfigModel, const QSharedPointer<XrayConfigModel> &xrayConfigModel,
#ifdef Q_OS_WINDOWS
const QSharedPointer<Ikev2ConfigModel> &ikev2ConfigModel,
#endif
const QSharedPointer<SftpConfigModel> &sftpConfigModel,
const QSharedPointer<Socks5ProxyConfigModel> &socks5ProxyConfigModel, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
public slots:
void updateModel(const QJsonObject &content);
void updateModel(const QMap<QString, QSharedPointer<ProtocolConfig>> &protocolConfigs);
void updateProtocolModel(amnezia::Proto protocol);
QJsonObject getConfig();
QMap<QString, QSharedPointer<ProtocolConfig>> getProtocolConfigs();
protected:
QHash<int, QByteArray> roleNames() const override;
@ -38,10 +59,19 @@ private:
PageLoader::PageEnum serverProtocolPage(Proto protocol) const;
PageLoader::PageEnum clientProtocolPage(Proto protocol) const;
std::shared_ptr<Settings> m_settings;
QVector<QSharedPointer<ProtocolConfig>> m_protocolConfigs;
DockerContainer m_container;
QJsonObject m_content;
QSharedPointer<OpenVpnConfigModel> m_openVpnConfigModel;
QSharedPointer<ShadowSocksConfigModel> m_shadowSocksConfigModel;
QSharedPointer<CloakConfigModel> m_cloakConfigModel;
QSharedPointer<WireGuardConfigModel> m_wireGuardConfigModel;
QSharedPointer<AwgConfigModel> m_awgConfigModel;
QSharedPointer<XrayConfigModel> m_xrayConfigModel;
#ifdef Q_OS_WINDOWS
QSharedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
#endif
QSharedPointer<SftpConfigModel> m_sftpConfigModel;
QSharedPointer<Socks5ProxyConfigModel> m_socks5ProxyConfigModel;
};
#endif // PROTOCOLS_MODEL_H

View file

@ -2,14 +2,16 @@
#include "core/api/apiDefs.h"
#include "core/controllers/serverController.h"
#include "core/models/servers/apiV1ServerConfig.h"
#include "core/models/servers/apiV2ServerConfig.h"
#include "core/models/servers/selfHostedServerConfig.h"
#include "core/models/servers/serverConfig.h"
#include "core/networkUtilities.h"
#ifdef Q_OS_IOS
#include <AmneziaVPN-Swift.h>
#endif
#include "core/api/apiUtils.h"
namespace
{
namespace configKey
@ -35,8 +37,7 @@ ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
connect(this, &ServersModel::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged);
connect(this, &ServersModel::defaultServerIndexChanged, this, [this](const int serverIndex) {
auto defaultContainer =
ContainerProps::containerFromString(m_servers.at(serverIndex).toObject().value(config_key::defaultContainer).toString());
auto defaultContainer = ContainerProps::containerFromString(m_servers1.at(serverIndex)->defaultContainer);
emit ServersModel::defaultServerDefaultContainerChanged(defaultContainer);
emit ServersModel::defaultServerNameChanged();
updateDefaultServerContainersModel();
@ -49,28 +50,25 @@ ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
int ServersModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return static_cast<int>(m_servers.size());
return static_cast<int>(m_servers1.size());
}
bool ServersModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(m_servers.size())) {
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(m_servers1.size())) {
return false;
}
QJsonObject server = m_servers.at(index.row()).toObject();
const auto configVersion = server.value(config_key::configVersion).toInt();
QSharedPointer<ServerConfig> serverConfig = m_servers1.at(index.row());
ServerConfigVariant variant = ServerConfig::getServerConfigVariant(serverConfig);
switch (role) {
case NameRole: {
if (configVersion) {
server.insert(config_key::name, value.toString());
} 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);
std::visit([&value](const auto &ptr) -> void { ptr->name = value.toString(); }, variant);
serverConfig->nameOverriddenByUser = true;
m_settings->editServer(index.row(), serverConfig->toJson());
m_servers1.replace(index.row(), serverConfig);
if (index.row() == m_defaultServerIndex) {
emit defaultServerNameChanged();
}
@ -93,29 +91,21 @@ bool ServersModel::setData(const int index, const QVariant &value, int role)
QVariant ServersModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(m_servers.size())) {
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(m_servers1.size())) {
return QVariant();
}
const QJsonObject server = m_servers.at(index.row()).toObject();
const auto apiConfig = server.value(configKey::apiConfig).toObject();
const auto configVersion = server.value(config_key::configVersion).toInt();
QSharedPointer<ServerConfig> serverConfig = m_servers1.at(index.row());
ServerConfigVariant variant = ServerConfig::getServerConfigVariant(serverConfig);
switch (role) {
case NameRole: {
if (configVersion) {
return server.value(config_key::name).toString();
}
auto name = server.value(config_key::description).toString();
if (name.isEmpty()) {
return server.value(config_key::hostName).toString();
}
return name;
return std::visit([](const auto &ptr) -> QString { return ptr->name; }, variant);
}
case ServerDescriptionRole: {
auto description = getServerDescription(server, index.row());
return configVersion ? description : description + server.value(config_key::hostName).toString();
return getServerDescription(index.row());
}
case HostNameRole: return server.value(config_key::hostName).toString();
case HostNameRole: return serverConfig->hostName;
case CredentialsRole: return QVariant::fromValue(serverCredentials(index.row()));
case CredentialsLoginRole: return serverCredentials(index.row()).userName;
case IsDefaultRole: return index.row() == m_defaultServerIndex;
@ -125,36 +115,28 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty());
}
case ContainsAmneziaDnsRole: {
QString primaryDns = server.value(config_key::dns1).toString();
return primaryDns == protocols::dns::amneziaDnsIp;
return serverConfig->dns1 == protocols::dns::amneziaDnsIp;
}
case DefaultContainerRole: {
return ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
return ContainerProps::containerFromString(serverConfig->defaultContainer);
}
case HasInstalledContainers: {
return serverHasInstalledContainers(index.row());
}
case IsServerFromTelegramApiRole: {
return server.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::Telegram;
return serverConfig->type == amnezia::ServerConfigType::ApiV1;
}
case IsServerFromGatewayApiRole: {
return server.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway;
}
case ApiConfigRole: {
return apiConfig;
return serverConfig->type == amnezia::ServerConfigType::ApiV2;
}
case IsCountrySelectionAvailableRole: {
return !apiConfig.value(configKey::availableCountries).toArray().isEmpty();
return !qSharedPointerCast<ApiV2ServerConfig>(serverConfig)->apiConfig.availableCountries.isEmpty();
}
case ApiAvailableCountriesRole: {
return apiConfig.value(configKey::availableCountries).toArray();
return QVariant::fromValue(qSharedPointerCast<ApiV2ServerConfig>(serverConfig)->apiConfig.availableCountries);
}
case ApiServerCountryCodeRole: {
return apiConfig.value(configKey::serverCountryCode).toString();
}
case HasAmneziaDns: {
QString primaryDns = server.value(config_key::dns1).toString();
return primaryDns == protocols::dns::amneziaDnsIp;
return qSharedPointerCast<ApiV2ServerConfig>(serverConfig)->apiConfig.serverCountryCode;
}
}
@ -170,9 +152,15 @@ QVariant ServersModel::data(const int index, int role) const
void ServersModel::resetModel()
{
beginResetModel();
m_servers = m_settings->serversArray();
auto servers = m_settings->serversArray();
m_defaultServerIndex = m_settings->defaultServerIndex();
m_processedServerIndex = m_defaultServerIndex;
for (auto server : servers) {
auto serverConfig = ServerConfig::createServerConfig(server.toObject());
m_servers1.push_back(serverConfig);
}
endResetModel();
emit defaultServerIndexChanged(m_defaultServerIndex);
}
@ -194,58 +182,64 @@ const QString ServersModel::getDefaultServerName()
return qvariant_cast<QString>(data(m_defaultServerIndex, NameRole));
}
QString ServersModel::getServerDescription(const QJsonObject &server, const int index) const
QString ServersModel::getServerDescription(const int index) const
{
const auto configVersion = server.value(config_key::configVersion).toInt();
const auto apiConfig = server.value(configKey::apiConfig).toObject();
QString description;
if (configVersion && !apiConfig.value(configKey::serverCountryCode).toString().isEmpty()) {
return apiConfig.value(configKey::serverCountryName).toString();
} else if (configVersion) {
return server.value(config_key::description).toString();
} else if (data(index, HasWriteAccessRole).toBool()) {
if (m_isAmneziaDnsEnabled && isAmneziaDnsContainerInstalled(index)) {
description += "Amnezia DNS | ";
}
} else {
if (data(index, HasAmneziaDns).toBool()) {
description += "Amnezia DNS | ";
auto serverConfig = m_servers1.at(index);
switch (serverConfig->type) {
case amnezia::ServerConfigType::ApiV1: return qSharedPointerCast<ApiV1ServerConfig>(serverConfig)->description;
case amnezia::ServerConfigType::ApiV2: {
auto apiV2ServerConfig = qSharedPointerCast<ApiV2ServerConfig>(serverConfig);
if (apiV2ServerConfig->apiConfig.serverCountryCode.isEmpty()) {
return apiV2ServerConfig->description;
} else {
return apiV2ServerConfig->apiConfig.serverCountryName;
}
}
return description;
case amnezia::ServerConfigType::SelfHosted: {
QString description;
if (data(index, HasWriteAccessRole).toBool()) {
if (m_isAmneziaDnsEnabled && isAmneziaDnsContainerInstalled(index)) {
description += "Amnezia DNS | " + serverConfig->hostName;
}
} else {
if (data(index, ContainsAmneziaDnsRole).toBool()) {
description += "Amnezia DNS | " + serverConfig->hostName;
}
}
return description;
}
}
}
const QString ServersModel::getDefaultServerDescriptionCollapsed()
{
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
const auto configVersion = server.value(config_key::configVersion).toInt();
auto description = getServerDescription(server, m_defaultServerIndex);
if (configVersion) {
auto serverConfig = m_servers1.at(m_defaultServerIndex);
auto description = getServerDescription(m_defaultServerIndex);
auto containerName = ContainerProps::containerFromString(serverConfig->defaultContainer);
if (serverConfig->type != ServerConfigType::SelfHosted) {
return description;
}
auto container = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
return description += ContainerProps::containerHumanNames().value(container) + " | " + server.value(config_key::hostName).toString();
return description += ContainerProps::containerHumanNames().value(containerName) + " | " + serverConfig->hostName;
}
const QString ServersModel::getDefaultServerDescriptionExpanded()
{
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
const auto configVersion = server.value(config_key::configVersion).toInt();
auto description = getServerDescription(server, m_defaultServerIndex);
if (configVersion) {
auto serverConfig = m_servers1.at(m_defaultServerIndex);
auto description = getServerDescription(m_defaultServerIndex);
auto containerName = ContainerProps::containerFromString(serverConfig->defaultContainer);
if (serverConfig->type != ServerConfigType::SelfHosted) {
return description;
}
return description += server.value(config_key::hostName).toString();
return description += serverConfig->hostName;
}
const int ServersModel::getServersCount()
{
return m_servers.count();
return m_servers1.count();
}
bool ServersModel::hasServerWithWriteAccess()
@ -307,18 +301,22 @@ bool ServersModel::isDefaultServerHasWriteAccess()
return qvariant_cast<bool>(data(m_defaultServerIndex, HasWriteAccessRole));
}
void ServersModel::addServer(const QJsonObject &server)
void ServersModel::addServer(const QSharedPointer<ServerConfig> &serverConfig)
{
beginResetModel();
m_settings->addServer(server);
m_servers = m_settings->serversArray();
m_settings->addServer(serverConfig->toJson());
auto servers = m_settings->serversArray();
for (auto server : servers) {
auto serverConfig = ServerConfig::createServerConfig(server.toObject());
m_servers1.push_back(serverConfig);
}
endResetModel();
}
void ServersModel::editServer(const QJsonObject &server, const int serverIndex)
void ServersModel::editServer(const QSharedPointer<ServerConfig> &serverConfig, const int serverIndex)
{
m_settings->editServer(serverIndex, server);
m_servers.replace(serverIndex, m_settings->serversArray().at(serverIndex));
m_settings->editServer(serverIndex, serverConfig->toJson());
m_servers1[serverIndex] = serverConfig;
emit dataChanged(index(serverIndex, 0), index(serverIndex, 0));
if (serverIndex == m_defaultServerIndex) {
@ -332,30 +330,20 @@ void ServersModel::editServer(const QJsonObject &server, const int serverIndex)
}
}
void ServersModel::removeServer()
void ServersModel::removeProcessedServer()
{
beginResetModel();
m_settings->removeServer(m_processedServerIndex);
m_servers = m_settings->serversArray();
if (m_settings->defaultServerIndex() == m_processedServerIndex) {
setDefaultServerIndex(0);
} else if (m_settings->defaultServerIndex() > m_processedServerIndex) {
setDefaultServerIndex(m_settings->defaultServerIndex() - 1);
}
if (m_settings->serversCount() == 0) {
setDefaultServerIndex(-1);
}
setProcessedServerIndex(m_defaultServerIndex);
endResetModel();
removeServer(m_processedServerIndex);
}
void ServersModel::removeServer(const int serverIndex)
{
beginResetModel();
m_settings->removeServer(serverIndex);
m_servers = m_settings->serversArray();
auto servers = m_settings->serversArray();
for (auto server : servers) {
auto serverConfig = ServerConfig::createServerConfig(server.toObject());
m_servers1.push_back(serverConfig);
}
if (m_settings->defaultServerIndex() == serverIndex) {
setDefaultServerIndex(0);
@ -397,7 +385,6 @@ QHash<int, QByteArray> ServersModel::roleNames() const
roles[IsServerFromTelegramApiRole] = "isServerFromTelegramApi";
roles[IsServerFromGatewayApiRole] = "isServerFromGatewayApi";
roles[ApiConfigRole] = "apiConfig";
roles[IsCountrySelectionAvailableRole] = "isCountrySelectionAvailable";
roles[ApiAvailableCountriesRole] = "apiAvailableCountries";
roles[ApiServerCountryCodeRole] = "apiServerCountryCode";
@ -406,97 +393,33 @@ QHash<int, QByteArray> ServersModel::roleNames() const
ServerCredentials ServersModel::serverCredentials(int index) const
{
const QJsonObject &s = m_servers.at(index).toObject();
ServerCredentials credentials;
credentials.hostName = s.value(config_key::hostName).toString();
credentials.userName = s.value(config_key::userName).toString();
credentials.secretData = s.value(config_key::password).toString();
credentials.port = s.value(config_key::port).toInt();
return credentials;
const auto serverConfig = m_servers1.at(index);
return qSharedPointerCast<SelfHostedServerConfig>(serverConfig)->serverCredentials;
}
void ServersModel::updateContainersModel()
{
auto containers = m_servers.at(m_processedServerIndex).toObject().value(config_key::containers).toArray();
emit containersUpdated(containers);
auto containerConfigs = m_servers1.at(m_processedServerIndex)->containerConfigs;
emit containersUpdated(containerConfigs);
}
void ServersModel::updateDefaultServerContainersModel()
{
auto containers = m_servers.at(m_defaultServerIndex).toObject().value(config_key::containers).toArray();
emit defaultServerContainersUpdated(containers);
auto containerConfigs = m_servers1.at(m_defaultServerIndex)->containerConfigs;
emit defaultServerContainersUpdated(containerConfigs);
}
QJsonObject ServersModel::getServerConfig(const int serverIndex) const
QSharedPointer<const ServerConfig> ServersModel::getServerConfig(const int serverIndex)
{
return m_servers.at(serverIndex).toObject();
}
void ServersModel::reloadDefaultServerContainerConfig()
{
QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
auto container = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
auto containers = server.value(config_key::containers).toArray();
auto config = m_settings->containerConfig(m_defaultServerIndex, container);
for (auto i = 0; i < containers.size(); i++) {
auto c = ContainerProps::containerFromString(containers.at(i).toObject().value(config_key::container).toString());
if (c == container) {
containers.replace(i, config);
break;
}
}
server.insert(config_key::containers, containers);
editServer(server, m_defaultServerIndex);
}
void ServersModel::updateContainerConfig(const int containerIndex, const QJsonObject config)
{
auto container = static_cast<DockerContainer>(containerIndex);
QJsonObject server = m_servers.at(m_processedServerIndex).toObject();
auto containers = server.value(config_key::containers).toArray();
for (auto i = 0; i < containers.size(); i++) {
auto c = ContainerProps::containerFromString(containers.at(i).toObject().value(config_key::container).toString());
if (c == container) {
containers.replace(i, config);
break;
}
}
server.insert(config_key::containers, containers);
editServer(server, m_processedServerIndex);
}
void ServersModel::addContainerConfig(const int containerIndex, const QJsonObject config)
{
auto container = static_cast<DockerContainer>(containerIndex);
QJsonObject server = m_servers.at(m_processedServerIndex).toObject();
auto containers = server.value(config_key::containers).toArray();
containers.push_back(config);
server.insert(config_key::containers, containers);
auto defaultContainer = server.value(config_key::defaultContainer).toString();
if (ContainerProps::containerFromString(defaultContainer) == DockerContainer::None
&& ContainerProps::containerService(container) != ServiceType::Other && ContainerProps::isSupportedByCurrentPlatform(container)) {
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
}
editServer(server, m_processedServerIndex);
return m_servers1.at(serverIndex);
}
void ServersModel::setDefaultContainer(const int serverIndex, const int containerIndex)
{
auto container = static_cast<DockerContainer>(containerIndex);
QJsonObject s = m_servers.at(serverIndex).toObject();
s.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
editServer(s, serverIndex); // check
auto serverConfig = m_servers1.at(serverIndex);
serverConfig->defaultContainer = ContainerProps::containerToString(container);
editServer(serverConfig, serverIndex);
}
const QString ServersModel::getDefaultServerDefaultContainerName()
@ -507,25 +430,19 @@ const QString ServersModel::getDefaultServerDefaultContainerName()
ErrorCode ServersModel::removeAllContainers(const QSharedPointer<ServerController> &serverController)
{
ErrorCode errorCode = serverController->removeAllContainers(m_settings->serverCredentials(m_processedServerIndex));
if (errorCode == ErrorCode::NoError) {
QJsonObject s = m_servers.at(m_processedServerIndex).toObject();
s.insert(config_key::containers, {});
s.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
editServer(s, m_processedServerIndex);
auto serverConfig = m_servers1.at(m_processedServerIndex);
serverConfig->containerConfigs.clear();
editServer(serverConfig, m_processedServerIndex);
}
return errorCode;
}
ErrorCode ServersModel::rebootServer(const QSharedPointer<ServerController> &serverController)
{
auto credentials = m_settings->serverCredentials(m_processedServerIndex);
ErrorCode errorCode = serverController->rebootServer(credentials);
ErrorCode errorCode = serverController->rebootServer(m_settings->serverCredentials(m_processedServerIndex));
return errorCode;
}
@ -538,30 +455,19 @@ ErrorCode ServersModel::removeContainer(const QSharedPointer<ServerController> &
ErrorCode errorCode = serverController->removeContainer(credentials, dockerContainer);
if (errorCode == ErrorCode::NoError) {
QJsonObject server = m_servers.at(m_processedServerIndex).toObject();
auto serverConfig = m_servers1.at(m_processedServerIndex);
serverConfig->containerConfigs.remove(ContainerProps::containerToString(dockerContainer));
auto containers = server.value(config_key::containers).toArray();
for (auto it = containers.begin(); it != containers.end(); it++) {
if (it->toObject().value(config_key::container).toString() == ContainerProps::containerToString(dockerContainer)) {
containers.erase(it);
break;
}
}
server.insert(config_key::containers, containers);
auto defaultContainer = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
auto defaultContainer = ContainerProps::containerFromString(serverConfig->defaultContainer);
if (defaultContainer == containerIndex) {
if (containers.empty()) {
defaultContainer = DockerContainer::None;
if (serverConfig->containerConfigs.empty()) {
serverConfig->defaultContainer = ContainerProps::containerToString(DockerContainer::None);
} else {
defaultContainer =
ContainerProps::containerFromString(containers.begin()->toObject().value(config_key::container).toString());
serverConfig->defaultContainer = serverConfig->containerConfigs.begin()->containerName;
}
server.insert(config_key::defaultContainer, ContainerProps::containerToString(defaultContainer));
}
editServer(server, m_processedServerIndex);
editServer(serverConfig, m_processedServerIndex);
}
return errorCode;
}
@ -569,7 +475,9 @@ ErrorCode ServersModel::removeContainer(const QSharedPointer<ServerController> &
void ServersModel::clearCachedProfile(const DockerContainer container)
{
m_settings->clearLastConnectionConfig(m_processedServerIndex, container);
m_servers.replace(m_processedServerIndex, m_settings->server(m_processedServerIndex));
auto serverConfig = ServerConfig::createServerConfig(m_settings->server(m_processedServerIndex));
m_servers1.replace(m_processedServerIndex, serverConfig);
if (m_processedServerIndex == m_defaultServerIndex) {
updateDefaultServerContainersModel();
}
@ -578,10 +486,9 @@ void ServersModel::clearCachedProfile(const DockerContainer container)
bool ServersModel::isAmneziaDnsContainerInstalled(const int serverIndex) const
{
QJsonObject server = m_servers.at(serverIndex).toObject();
auto containers = server.value(config_key::containers).toArray();
for (auto it = containers.begin(); it != containers.end(); it++) {
if (it->toObject().value(config_key::container).toString() == ContainerProps::containerToString(DockerContainer::Dns)) {
auto serverConfig = m_servers1.at(serverIndex);
for (const auto &container : serverConfig->containerConfigs) {
if (container.containerName == ContainerProps::containerToString(DockerContainer::Dns)) {
return true;
}
}
@ -592,17 +499,16 @@ QPair<QString, QString> ServersModel::getDnsPair(int serverIndex)
{
QPair<QString, QString> dns;
const QJsonObject &server = m_servers.at(m_processedServerIndex).toObject();
const auto containers = server.value(config_key::containers).toArray();
auto serverConfig = m_servers1.at(serverIndex);
bool isDnsContainerInstalled = false;
for (const QJsonValue &container : containers) {
if (ContainerProps::containerFromString(container.toObject().value(config_key::container).toString()) == DockerContainer::Dns) {
for (const auto &container : serverConfig->containerConfigs) {
if (container.containerName == ContainerProps::containerToString(DockerContainer::Dns)) {
isDnsContainerInstalled = true;
}
}
dns.first = server.value(config_key::dns1).toString();
dns.second = server.value(config_key::dns2).toString();
dns.first = serverConfig->dns1;
dns.second = serverConfig->dns2;
if (dns.first.isEmpty() || !NetworkUtilities::checkIPv4Format(dns.first)) {
if (m_isAmneziaDnsEnabled && isDnsContainerInstalled) {
@ -621,18 +527,17 @@ QPair<QString, QString> ServersModel::getDnsPair(int serverIndex)
QStringList ServersModel::getAllInstalledServicesName(const int serverIndex)
{
QStringList servicesName;
QJsonObject server = m_servers.at(serverIndex).toObject();
const auto containers = server.value(config_key::containers).toArray();
for (auto it = containers.begin(); it != containers.end(); it++) {
auto container = ContainerProps::containerFromString(it->toObject().value(config_key::container).toString());
if (ContainerProps::containerService(container) == ServiceType::Other) {
if (container == DockerContainer::Dns) {
auto serverConfig = m_servers1.at(serverIndex);
for (const auto &container : serverConfig->containerConfigs) {
auto containerType = ContainerProps::containerFromString(container.containerName);
if (ContainerProps::containerService(containerType) == ServiceType::Other) {
if (containerType == DockerContainer::Dns) {
servicesName.append("DNS");
} else if (container == DockerContainer::Sftp) {
} else if (containerType == DockerContainer::Sftp) {
servicesName.append("SFTP");
} else if (container == DockerContainer::TorWebSite) {
} else if (containerType == DockerContainer::TorWebSite) {
servicesName.append("TOR");
} else if (container == DockerContainer::Socks5Proxy) {
} else if (containerType == DockerContainer::Socks5Proxy) {
servicesName.append("SOCKS5");
}
}
@ -649,8 +554,8 @@ void ServersModel::toggleAmneziaDns(bool enabled)
bool ServersModel::isServerFromApiAlreadyExists(const quint16 crc)
{
for (const auto &server : std::as_const(m_servers)) {
if (static_cast<quint16>(server.toObject().value(config_key::crc).toInt()) == crc) {
for (const auto &server : std::as_const(m_servers1)) {
if (static_cast<quint16>(server->crc) == crc) {
return true;
}
}
@ -659,11 +564,10 @@ bool ServersModel::isServerFromApiAlreadyExists(const quint16 crc)
bool ServersModel::isServerFromApiAlreadyExists(const QString &userCountryCode, const QString &serviceType, const QString &serviceProtocol)
{
for (const auto &server : std::as_const(m_servers)) {
const auto apiConfig = server.toObject().value(configKey::apiConfig).toObject();
if (apiConfig.value(configKey::userCountryCode).toString() == userCountryCode
&& apiConfig.value(configKey::serviceType).toString() == serviceType
&& apiConfig.value(configKey::serviceProtocol).toString() == serviceProtocol) {
for (const auto &serverConfig : std::as_const(m_servers1)) {
const auto apiV2ServerConfig = qSharedPointerCast<ApiV2ServerConfig>(serverConfig);
if (apiV2ServerConfig->apiConfig.userCountryCode == userCountryCode && apiV2ServerConfig->apiConfig.serviceType == serviceType
&& apiV2ServerConfig->apiConfig.serviceProtocol == serviceProtocol) {
return true;
}
}
@ -672,14 +576,14 @@ bool ServersModel::isServerFromApiAlreadyExists(const QString &userCountryCode,
bool ServersModel::serverHasInstalledContainers(const int serverIndex) const
{
QJsonObject server = m_servers.at(serverIndex).toObject();
const auto containers = server.value(config_key::containers).toArray();
for (auto it = containers.begin(); it != containers.end(); it++) {
auto container = ContainerProps::containerFromString(it->toObject().value(config_key::container).toString());
if (ContainerProps::containerService(container) == ServiceType::Vpn) {
auto server = m_servers1.at(serverIndex);
const auto containers = server->containerConfigs;
for (const auto &container : containers) {
auto dockerContainer = ContainerProps::containerFromString(container.containerName);
if (ContainerProps::containerService(dockerContainer) == ServiceType::Vpn) {
return true;
}
if (container == DockerContainer::SSXray) {
if (dockerContainer == DockerContainer::SSXray) {
return true;
}
}
@ -724,27 +628,46 @@ bool ServersModel::setProcessedServerData(const QString &roleString, const QVari
bool ServersModel::isDefaultServerDefaultContainerHasSplitTunneling()
{
auto server = m_servers.at(m_defaultServerIndex).toObject();
auto defaultContainer = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
auto serverConfig = m_servers1.at(m_defaultServerIndex);
auto defaultContainer = ContainerProps::containerFromString(serverConfig->defaultContainer);
auto containers = server.value(config_key::containers).toArray();
for (auto i = 0; i < containers.size(); i++) {
auto container = containers.at(i).toObject();
if (container.value(config_key::container).toString() != ContainerProps::containerToString(defaultContainer)) {
for (const auto &container : serverConfig->containerConfigs) {
if (container.containerName != serverConfig->defaultContainer) {
continue;
}
if (defaultContainer == DockerContainer::Awg || defaultContainer == DockerContainer::WireGuard) {
QJsonObject serverProtocolConfig = container.value(ContainerProps::containerTypeToString(defaultContainer)).toObject();
QString clientProtocolConfigString = serverProtocolConfig.value(config_key::last_config).toString();
QJsonObject clientProtocolConfig = QJsonDocument::fromJson(clientProtocolConfigString.toUtf8()).object();
return (clientProtocolConfigString.contains("AllowedIPs") && !clientProtocolConfigString.contains("AllowedIPs = 0.0.0.0/0, ::/0"))
|| (!clientProtocolConfig.value(config_key::allowed_ips).toArray().isEmpty()
&& !clientProtocolConfig.value(config_key::allowed_ips).toArray().contains("0.0.0.0/0"));
auto protocolConfigVariant = ProtocolConfig::getProtocolConfigVariant(container.protocolConfigs[serverConfig->defaultContainer]);
return std::visit(
[](const auto &ptr) -> bool {
if constexpr (requires {
ptr->clientProtocolConfig;
ptr->clientProtocolConfig.wireGuardData;
}) {
const auto nativeConfig = ptr->clientProtocolConfig.nativeConfig;
const auto allowedIps = ptr->clientProtocolConfig.wireGuardData.allowedIps;
return (nativeConfig.contains("AllowedIPs") && !nativeConfig.contains("AllowedIPs = 0.0.0.0/0, ::/0"))
|| (!allowedIps.isEmpty() && !allowedIps.contains("0.0.0.0/0"));
} else {
return false;
}
},
protocolConfigVariant);
} else if (defaultContainer == DockerContainer::Cloak || defaultContainer == DockerContainer::OpenVpn
|| defaultContainer == DockerContainer::ShadowSocks) {
auto serverProtocolConfig = container.value(ContainerProps::containerTypeToString(DockerContainer::OpenVpn)).toObject();
QString clientProtocolConfigString = serverProtocolConfig.value(config_key::last_config).toString();
return !clientProtocolConfigString.isEmpty() && !clientProtocolConfigString.contains("redirect-gateway");
auto protocolConfigVariant = ProtocolConfig::getProtocolConfigVariant(
container.protocolConfigs[ContainerProps::containerTypeToString(DockerContainer::OpenVpn)]);
return std::visit(
[](const auto &ptr) -> bool {
if constexpr (requires { ptr->clientProtocolConfig; }) {
const auto nativeConfig = ptr->clientProtocolConfig.nativeConfig;
return (!nativeConfig.isEmpty() && !nativeConfig.contains("redirect-gateway"));
} else {
return false;
}
},
protocolConfigVariant);
}
}
return false;
@ -757,67 +680,62 @@ bool ServersModel::isServerFromApi(const int serverIndex)
bool ServersModel::isApiKeyExpired(const int serverIndex)
{
auto serverConfig = m_servers.at(serverIndex).toObject();
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
// auto serverConfig = m_servers1.at(serverIndex);
// auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
auto publicKeyInfo = apiConfig.value(configKey::publicKeyInfo).toObject();
const QString expiresAt = publicKeyInfo.value(configKey::expiresAt).toString();
if (expiresAt.isEmpty()) {
publicKeyInfo.insert(configKey::expiresAt, QDateTime::currentDateTimeUtc().addDays(1).toString(Qt::ISODate));
apiConfig.insert(configKey::publicKeyInfo, publicKeyInfo);
serverConfig.insert(configKey::apiConfig, apiConfig);
editServer(serverConfig, serverIndex);
// auto publicKeyInfo = apiConfig.value(configKey::publicKeyInfo).toObject();
// const QString expiresAt = publicKeyInfo.value(configKey::expiresAt).toString();
// if (expiresAt.isEmpty()) {
// publicKeyInfo.insert(configKey::expiresAt, QDateTime::currentDateTimeUtc().addDays(1).toString(Qt::ISODate));
// apiConfig.insert(configKey::publicKeyInfo, publicKeyInfo);
// serverConfig.insert(configKey::apiConfig, apiConfig);
// editServer(serverConfig, serverIndex);
return false;
}
// return false;
// }
auto expiresAtDateTime = QDateTime::fromString(expiresAt, Qt::ISODate).toUTC();
if (expiresAtDateTime < QDateTime::currentDateTimeUtc()) {
return true;
}
return false;
// auto expiresAtDateTime = QDateTime::fromString(expiresAt, Qt::ISODate).toUTC();
// if (expiresAtDateTime < QDateTime::currentDateTimeUtc()) {
// return true;
// }
// return false;
}
void ServersModel::removeApiConfig(const int serverIndex)
{
auto serverConfig = getServerConfig(serverIndex);
// auto serverConfig = m_servers1.at(serverIndex);
#ifdef Q_OS_IOS
QString vpncName = QString("%1 (%2) %3")
.arg(serverConfig[config_key::description].toString())
.arg(serverConfig[config_key::hostName].toString())
.arg(serverConfig[config_key::vpnproto].toString());
// #ifdef Q_OS_IOS
// QString vpncName = QString("%1 (%2) %3")
// .arg(serverConfig[config_key::description].toString())
// .arg(serverConfig[config_key::hostName].toString())
// .arg(serverConfig[config_key::vpnproto].toString());
AmneziaVPN::removeVPNC(vpncName.toStdString());
#endif
// AmneziaVPN::removeVPNC(vpncName.toStdString());
// #endif
serverConfig.remove(config_key::dns1);
serverConfig.remove(config_key::dns2);
serverConfig.remove(config_key::containers);
serverConfig.remove(config_key::hostName);
// serverConfig.remove(config_key::dns1);
// serverConfig.remove(config_key::dns2);
// serverConfig.remove(config_key::containers);
// serverConfig.remove(config_key::hostName);
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
apiConfig.remove(configKey::publicKeyInfo);
serverConfig.insert(configKey::apiConfig, apiConfig);
// auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
// apiConfig.remove(configKey::publicKeyInfo);
// serverConfig.insert(configKey::apiConfig, apiConfig);
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
// serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
editServer(serverConfig, serverIndex);
// editServer(serverConfig, serverIndex);
}
const QString ServersModel::getDefaultServerImagePathCollapsed()
{
const auto server = m_servers.at(m_defaultServerIndex).toObject();
const auto apiConfig = server.value(configKey::apiConfig).toObject();
const auto countryCode = apiConfig.value(configKey::serverCountryCode).toString();
// const auto server = m_servers.at(m_defaultServerIndex).toObject();
// const auto apiConfig = server.value(configKey::apiConfig).toObject();
// const auto countryCode = apiConfig.value(configKey::serverCountryCode).toString();
if (countryCode.isEmpty()) {
return "";
}
return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(countryCode.toUpper());
}
bool ServersModel::processedServerIsPremium() const
{
return apiUtils::isPremiumServer(getServerConfig(m_processedServerIndex));
// if (countryCode.isEmpty()) {
// return "";
// }
// return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(countryCode.toUpper());
}

View file

@ -4,6 +4,7 @@
#include <QAbstractListModel>
#include "core/controllers/serverController.h"
#include "core/models/servers/serverConfig.h"
#include "settings.h"
class ServersModel : public QAbstractListModel
@ -36,9 +37,7 @@ public:
ApiConfigRole,
IsCountrySelectionAvailableRole,
ApiAvailableCountriesRole,
ApiServerCountryCodeRole,
HasAmneziaDns
ApiServerCountryCodeRole
};
ServersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
@ -63,9 +62,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);
@ -90,16 +86,12 @@ public slots:
const ServerCredentials getProcessedServerCredentials();
const ServerCredentials getServerCredentials(const int index);
void addServer(const QJsonObject &server);
void editServer(const QJsonObject &server, const int serverIndex);
void removeServer();
void addServer(const QSharedPointer<ServerConfig> &serverConfig);
void editServer(const QSharedPointer<ServerConfig> &serverConfig, const int serverIndex);
void removeProcessedServer();
void removeServer(const int serverIndex);
QJsonObject getServerConfig(const int serverIndex) const;
void reloadDefaultServerContainerConfig();
void updateContainerConfig(const int containerIndex, const QJsonObject config);
void addContainerConfig(const int containerIndex, const QJsonObject config);
QSharedPointer<const ServerConfig> getServerConfig(const int serverIndex);
void clearCachedProfile(const DockerContainer container);
@ -140,8 +132,8 @@ signals:
void defaultServerNameChanged();
void defaultServerDescriptionChanged();
void containersUpdated(const QJsonArray &containers);
void defaultServerContainersUpdated(const QJsonArray &containers);
void containersUpdated(const QMap<QString, ContainerConfig> &containerConfigs);
void defaultServerContainersUpdated(const QMap<QString, ContainerConfig> &containerConfigs);
void defaultServerDefaultContainerChanged(const int containerIndex);
void updateApiCountryModel();
@ -153,13 +145,13 @@ private:
void updateContainersModel();
void updateDefaultServerContainersModel();
QString getServerDescription(const QJsonObject &server, const int index) const;
QString getServerDescription(const int index) const;
bool isAmneziaDnsContainerInstalled(const int serverIndex) const;
bool serverHasInstalledContainers(const int serverIndex) const;
QJsonArray m_servers;
QVector<QSharedPointer<ServerConfig>> m_servers1;
std::shared_ptr<Settings> m_settings;

View file

@ -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
}

View file

@ -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,144 +150,28 @@ 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
}
}
}
AwgTextField {
id: specialJunk1TextField
headerText: qsTr("I1 - First special junk packet")
textField.text: clientSpecialJunk1
textField.validator: null
checkEmptyText: false
checkEmptyText: true
textField.onEditingFinished: {
if (textField.text !== clientSpecialJunk1) {
clientSpecialJunk1 = textField.text
}
}
}
AwgTextField {
id: specialJunk2TextField
headerText: qsTr("I2 - Second special junk packet")
textField.text: clientSpecialJunk2
textField.validator: null
checkEmptyText: false
textField.onEditingFinished: {
if (textField.text !== clientSpecialJunk2) {
clientSpecialJunk2 = textField.text
}
}
}
AwgTextField {
id: specialJunk3TextField
headerText: qsTr("I3 - Third special junk packet")
textField.text: clientSpecialJunk3
textField.validator: null
checkEmptyText: false
textField.onEditingFinished: {
if (textField.text !== clientSpecialJunk3) {
clientSpecialJunk3 = textField.text
}
}
}
AwgTextField {
id: specialJunk4TextField
headerText: qsTr("I4 - Fourth special junk packet")
textField.text: clientSpecialJunk4
textField.validator: null
checkEmptyText: false
textField.onEditingFinished: {
if (textField.text !== clientSpecialJunk4) {
clientSpecialJunk4 = textField.text
}
}
}
AwgTextField {
id: specialJunk5TextField
headerText: qsTr("I5 - Fifth special junk packet")
textField.text: clientSpecialJunk5
textField.validator: null
checkEmptyText: false
textField.onEditingFinished: {
if (textField.text !== clientSpecialJunk5 ) {
clientSpecialJunk5 = textField.text
}
}
}
AwgTextField {
id: controlledJunk1TextField
headerText: qsTr("J1 - First controlled junk packet")
textField.text: clientControlledJunk1
textField.validator: null
checkEmptyText: false
textField.onEditingFinished: {
if (textField.text !== clientControlledJunk1) {
clientControlledJunk1 = textField.text
}
}
}
AwgTextField {
id: controlledJunk2TextField
headerText: qsTr("J2 - Second controlled junk packet")
textField.text: clientControlledJunk2
textField.validator: null
checkEmptyText: false
textField.onEditingFinished: {
if (textField.text !== clientControlledJunk2) {
clientControlledJunk2 = textField.text
}
}
}
AwgTextField {
id: controlledJunk3TextField
headerText: qsTr("J3 - Third controlled junk packet")
textField.text: clientControlledJunk3
textField.validator: null
checkEmptyText: false
textField.onEditingFinished: {
if (textField.text !== clientControlledJunk3) {
clientControlledJunk3 = textField.text
}
}
}
AwgTextField {
id: iTimeTextField
headerText: qsTr("Itime - Special handshake timeout")
textField.text: clientSpecialHandshakeTimeout
checkEmptyText: false
textField.onEditingFinished: {
if (textField.text !== clientSpecialHandshakeTimeout) {
clientSpecialHandshakeTimeout = textField.text
}
}
}
Header2TextType {
@ -287,78 +181,82 @@ 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"
textField.text: serverTransportPacketMagicHeader
}
}
}
}

View file

@ -138,138 +138,183 @@ 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 {
id: underloadPacketMagicHeaderTextField
headerText: qsTr("H3 - Underload packet magic header")
textField.text: serverUnderloadPacketMagicHeader
textField.onEditingFinished: {
if (textField.text !== serverUnderloadPacketMagicHeader) {
serverUnderloadPacketMagicHeader = textField.text
}
}
}
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
}
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
}
BasicButtonType {
id: saveRestartButton
@ -283,8 +328,6 @@ PageType {
responsePacketMagicHeaderTextField.errorText === "" &&
initPacketMagicHeaderTextField.errorText === "" &&
responsePacketJunkSizeTextField.errorText === "" &&
// cookieReplyHeaderJunkTextField.errorText === "" &&
// transportHeaderJunkTextField.errorText === "" &&
initPacketJunkSizeTextField.errorText === "" &&
junkPacketMaxSizeTextField.errorText === "" &&
junkPacketMinSizeTextField.errorText === "" &&
@ -317,13 +360,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?")

View file

@ -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()
}
}
}

View file

@ -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()
}
}
}

View file

@ -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()
}
}
}

View file

@ -152,7 +152,7 @@ PageType {
}
var noButtonFunction = function() {
if (!GC.isMobile()) {
saveButton.forceActiveFocus()
saveRestartButton.forceActiveFocus()
}
}
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)

View file

@ -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()
}
}
}

View file

@ -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

View file

@ -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")

View file

@ -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")
}
}
}

View file

@ -101,10 +101,7 @@ PageType {
clickedFunction: function() {
if (isClientProtocolExists) {
switch (protocolIndex) {
case ProtocolEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ProtocolEnum.Awg: AwgConfigModel.updateModel(ProtocolsModel.getConfig()); break;
}
ProtocolsModel.updateProtocolModel(protocolIndex)
PageController.goToPage(clientProtocolPage);
} else {
PageController.showNotificationMessage(qsTr("Click the \"connect\" button to create a connection configuration"))
@ -132,17 +129,7 @@ PageType {
visible: delegateContent.isServerSettingsVisible
clickedFunction: function() {
switch (protocolIndex) {
case ProtocolEnum.OpenVpn: OpenVpnConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ProtocolEnum.ShadowSocks: ShadowSocksConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ProtocolEnum.Cloak: CloakConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ProtocolEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ProtocolEnum.Awg: AwgConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ProtocolEnum.Xray: XrayConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ProtocolEnum.Sftp: SftpConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ProtocolEnum.Ipsec: Ikev2ConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ProtocolEnum.Socks5Proxy: Socks5ProxyConfigModel.updateModel(ProtocolsModel.getConfig()); break;
}
ProtocolsModel.updateProtocolModel(protocolIndex)
PageController.goToPage(serverProtocolPage);
}

View file

@ -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(),

Some files were not shown because too many files have changed in this diff Show more