refactoring: remove json usuage from cinfugurators

This commit is contained in:
vladimir.kuznetsov
2025-08-04 16:10:31 +08:00
parent 76413ec2df
commit 6b0c543fd2
41 changed files with 1023 additions and 503 deletions

View File

@@ -9,16 +9,24 @@ AwgConfigurator::AwgConfigurator(std::shared_ptr<Settings> settings, const QShar
{
}
QString AwgConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
ErrorCode &errorCode)
QSharedPointer<ProtocolConfig> AwgConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode)
{
QString config = WireguardConfigurator::createConfig(credentials, container, containerConfig, errorCode);
QJsonObject jsonConfig = QJsonDocument::fromJson(config.toUtf8()).object();
QString awgConfig = jsonConfig.value(config_key::config).toString();
auto result = WireguardConfigurator::createConfig(credentials, container, protocolConfig, errorCode);
if (!result) {
return nullptr;
}
auto awgConfig = qSharedPointerCast<AwgProtocolConfig>(result);
if (!awgConfig) {
errorCode = ErrorCode::InternalError;
return nullptr;
}
QString config = awgConfig->clientProtocolConfig.nativeConfig;
QMap<QString, QString> configMap;
auto configLines = awgConfig.split("\n");
auto configLines = config.split("\n");
for (auto &line : configLines) {
auto trimmedLine = line.trimmed();
if (trimmedLine.startsWith("[") && trimmedLine.endsWith("]")) {
@@ -31,31 +39,17 @@ QString AwgConfigurator::createConfig(const ServerCredentials &credentials, Dock
}
}
jsonConfig[config_key::junkPacketCount] = configMap.value(config_key::junkPacketCount);
jsonConfig[config_key::junkPacketMinSize] = configMap.value(config_key::junkPacketMinSize);
jsonConfig[config_key::junkPacketMaxSize] = configMap.value(config_key::junkPacketMaxSize);
jsonConfig[config_key::initPacketJunkSize] = configMap.value(config_key::initPacketJunkSize);
jsonConfig[config_key::responsePacketJunkSize] = configMap.value(config_key::responsePacketJunkSize);
jsonConfig[config_key::initPacketMagicHeader] = configMap.value(config_key::initPacketMagicHeader);
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);
awgConfig->clientProtocolConfig.awgData.junkPacketCount = configMap.value(config_key::junkPacketCount);
awgConfig->clientProtocolConfig.awgData.junkPacketMinSize = configMap.value(config_key::junkPacketMinSize);
awgConfig->clientProtocolConfig.awgData.junkPacketMaxSize = configMap.value(config_key::junkPacketMaxSize);
awgConfig->clientProtocolConfig.awgData.initPacketJunkSize = configMap.value(config_key::initPacketJunkSize);
awgConfig->clientProtocolConfig.awgData.responsePacketJunkSize = configMap.value(config_key::responsePacketJunkSize);
awgConfig->clientProtocolConfig.awgData.initPacketMagicHeader = configMap.value(config_key::initPacketMagicHeader);
awgConfig->clientProtocolConfig.awgData.responsePacketMagicHeader = configMap.value(config_key::responsePacketMagicHeader);
awgConfig->clientProtocolConfig.awgData.underloadPacketMagicHeader = configMap.value(config_key::underloadPacketMagicHeader);
awgConfig->clientProtocolConfig.awgData.transportPacketMagicHeader = configMap.value(config_key::transportPacketMagicHeader);
// jsonConfig[config_key::cookieReplyPacketJunkSize] = configMap.value(config_key::cookieReplyPacketJunkSize);
// jsonConfig[config_key::transportPacketJunkSize] = configMap.value(config_key::transportPacketJunkSize);
awgConfig->clientProtocolConfig.wireGuardData.mtu = awgConfig->serverProtocolConfig.mtu;
// 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);
return QJsonDocument(jsonConfig).toJson();
return awgConfig;
}

View File

@@ -11,8 +11,8 @@ class AwgConfigurator : public WireguardConfigurator
public:
AwgConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode);
QSharedPointer<ProtocolConfig> createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode) override;
};
#endif // AWGCONFIGURATOR_H

View File

@@ -6,21 +6,45 @@
#include "core/models/containers/containers_defs.h"
#include "core/controllers/selfhosted/serverController.h"
#include "core/models/protocols/cloakProtocolConfig.h"
#include "protocols/protocols_defs.h"
CloakConfigurator::CloakConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent)
: ConfiguratorBase(settings, serverController, parent)
{
}
QString CloakConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
ErrorCode &errorCode)
ConfiguratorBase::Vars CloakConfigurator::generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const
{
Vars vars = generateCommonVars(credentials, container);
auto cloakConfig = qSharedPointerCast<CloakProtocolConfig>(protocolConfig);
if (!cloakConfig) {
return vars;
}
vars.append({{"$CLOAK_SERVER_PORT", cloakConfig->serverProtocolConfig.port}});
vars.append({{"$FAKE_WEB_SITE_ADDRESS", cloakConfig->serverProtocolConfig.site}});
return vars;
}
QSharedPointer<ProtocolConfig> CloakConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode)
{
auto cloakConfig = qSharedPointerCast<CloakProtocolConfig>(protocolConfig);
if (!cloakConfig) {
errorCode = ErrorCode::InternalError;
return nullptr;
}
QString cloakPublicKey =
m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::cloak::ckPublicKeyPath, errorCode);
cloakPublicKey.replace("\n", "");
if (errorCode != ErrorCode::NoError) {
return "";
return nullptr;
}
QString cloakBypassUid =
@@ -28,24 +52,38 @@ QString CloakConfigurator::createConfig(const ServerCredentials &credentials, Do
cloakBypassUid.replace("\n", "");
if (errorCode != ErrorCode::NoError) {
return "";
return nullptr;
}
cloakConfig->clientProtocolConfig.transport = "direct";
cloakConfig->clientProtocolConfig.proxyMethod = "openvpn";
cloakConfig->clientProtocolConfig.encryptionMethod = "aes-gcm";
cloakConfig->clientProtocolConfig.uid = cloakBypassUid;
cloakConfig->clientProtocolConfig.publicKey = cloakPublicKey;
cloakConfig->clientProtocolConfig.serverName = cloakConfig->serverProtocolConfig.site;
cloakConfig->clientProtocolConfig.numConn = 1;
cloakConfig->clientProtocolConfig.browserSig = "chrome";
cloakConfig->clientProtocolConfig.streamTimeout = 300;
cloakConfig->clientProtocolConfig.remoteHost = credentials.hostName;
cloakConfig->clientProtocolConfig.remotePort = cloakConfig->serverProtocolConfig.port;
QJsonObject config;
config.insert("Transport", "direct");
config.insert("ProxyMethod", "openvpn");
config.insert("EncryptionMethod", "aes-gcm");
config.insert("UID", cloakBypassUid);
config.insert("PublicKey", cloakPublicKey);
config.insert("ServerName", "$FAKE_WEB_SITE_ADDRESS");
config.insert("NumConn", 1);
config.insert("BrowserSig", "chrome");
config.insert("StreamTimeout", 300);
config.insert("RemoteHost", credentials.hostName);
config.insert("RemotePort", "$CLOAK_SERVER_PORT");
config.insert("Transport", cloakConfig->clientProtocolConfig.transport);
config.insert("ProxyMethod", cloakConfig->clientProtocolConfig.proxyMethod);
config.insert("EncryptionMethod", cloakConfig->clientProtocolConfig.encryptionMethod);
config.insert("UID", cloakConfig->clientProtocolConfig.uid);
config.insert("PublicKey", cloakConfig->clientProtocolConfig.publicKey);
config.insert("ServerName", cloakConfig->clientProtocolConfig.serverName);
config.insert("NumConn", cloakConfig->clientProtocolConfig.numConn);
config.insert("BrowserSig", cloakConfig->clientProtocolConfig.browserSig);
config.insert("StreamTimeout", cloakConfig->clientProtocolConfig.streamTimeout);
config.insert("RemoteHost", cloakConfig->clientProtocolConfig.remoteHost);
config.insert("RemotePort", cloakConfig->clientProtocolConfig.remotePort);
QString textCfg = m_serverController->replaceVars(QJsonDocument(config).toJson(),
m_serverController->genVarsForScript(credentials, container, containerConfig));
QString textCfg = QJsonDocument(config).toJson();
return textCfg;
cloakConfig->clientProtocolConfig.isEmpty = false;
cloakConfig->clientProtocolConfig.nativeConfig = textCfg;
return cloakConfig;
}

View File

@@ -4,6 +4,7 @@
#include <QObject>
#include "configurator_base.h"
#include "core/models/protocols/cloakProtocolConfig.h"
using namespace amnezia;
@@ -13,8 +14,11 @@ class CloakConfigurator : public ConfiguratorBase
public:
CloakConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode);
QSharedPointer<ProtocolConfig> createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode) override;
Vars generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const override;
};
#endif // CLOAK_CONFIGURATOR_H

View File

@@ -1,4 +1,5 @@
#include "configurator_base.h"
#include "core/networkUtilities.h"
ConfiguratorBase::ConfiguratorBase(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent)
: QObject { parent }, m_settings(settings), m_serverController(serverController)
@@ -24,3 +25,31 @@ void ConfiguratorBase::processConfigWithDnsSettings(const QPair<QString, QString
protocolConfigString.replace("$PRIMARY_DNS", dns.first);
protocolConfigString.replace("$SECONDARY_DNS", dns.second);
}
ConfiguratorBase::Vars ConfiguratorBase::generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const
{
return generateCommonVars(credentials, container);
}
ConfiguratorBase::Vars ConfiguratorBase::generateCommonVars(const ServerCredentials &credentials, DockerContainer container) const
{
Vars vars;
vars.append({{"$REMOTE_HOST", credentials.hostName}});
QString serverIp = (container != DockerContainer::Awg && container != DockerContainer::WireGuard && container != DockerContainer::Xray)
? NetworkUtilities::getIPAddress(credentials.hostName)
: credentials.hostName;
if (!serverIp.isEmpty()) {
vars.append({{"$SERVER_IP_ADDRESS", serverIp}});
}
vars.append({{"$CONTAINER_NAME", ContainerProps::containerToString(container)}});
vars.append({{"$DOCKERFILE_FOLDER", "/opt/amnezia/" + ContainerProps::containerToString(container)}});
vars.append({{"$PRIMARY_SERVER_DNS", m_settings->primaryDns()}});
vars.append({{"$SECONDARY_SERVER_DNS", m_settings->secondaryDns()}});
return vars;
}

View File

@@ -2,29 +2,40 @@
#define CONFIGURATORBASE_H
#include <QObject>
#include <QList>
#include <QPair>
#include <QSharedPointer>
#include "core/models/containers/containers_defs.h"
#include "core/defs.h"
#include "core/controllers/selfhosted/serverController.h"
#include "core/models/protocols/protocolConfig.h"
#include "settings.h"
class ConfiguratorBase : public QObject
{
Q_OBJECT
public:
using Vars = QList<QPair<QString, QString>>;
explicit ConfiguratorBase(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
virtual QString createConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode) = 0;
virtual QSharedPointer<ProtocolConfig> createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode) = 0;
virtual QString processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
QString &protocolConfigString);
virtual QString processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
QString &protocolConfigString);
virtual Vars generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const;
protected:
void processConfigWithDnsSettings(const QPair<QString, QString> &dns, QString &protocolConfigString);
Vars generateCommonVars(const ServerCredentials &credentials, DockerContainer container) const;
std::shared_ptr<Settings> m_settings;
QSharedPointer<ServerController> m_serverController;

View File

@@ -12,6 +12,7 @@
#include "core/controllers/selfhosted/serverController.h"
#include "core/scripts_registry.h"
#include "core/server_defs.h"
#include "protocols/protocols_defs.h"
#include "utilities.h"
Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent)
@@ -19,6 +20,28 @@ Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, const Q
{
}
ConfiguratorBase::Vars Ikev2Configurator::generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const
{
Vars vars = generateCommonVars(credentials, container);
vars.append({{"$IPSEC_VPN_L2TP_NET", "192.168.42.0/24"}});
vars.append({{"$IPSEC_VPN_L2TP_POOL", "192.168.42.10-192.168.42.250"}});
vars.append({{"$IPSEC_VPN_L2TP_LOCAL", "192.168.42.1"}});
vars.append({{"$IPSEC_VPN_XAUTH_NET", "192.168.43.0/24"}});
vars.append({{"$IPSEC_VPN_XAUTH_POOL", "192.168.43.10-192.168.43.250"}});
vars.append({{"$IPSEC_VPN_SHA2_TRUNCBUG", "yes"}});
vars.append({{"$IPSEC_VPN_VPN_ANDROID_MTU_FIX", "yes"}});
vars.append({{"$IPSEC_VPN_DISABLE_IKEV2", "no"}});
vars.append({{"$IPSEC_VPN_DISABLE_L2TP", "no"}});
vars.append({{"$IPSEC_VPN_DISABLE_XAUTH", "no"}});
vars.append({{"$IPSEC_VPN_C2C_TRAFFIC", "no"}});
return vars;
}
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials, DockerContainer container,
ErrorCode &errorCode)
{
@@ -54,21 +77,58 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
return connData;
}
QString Ikev2Configurator::createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
ErrorCode &errorCode)
QSharedPointer<ProtocolConfig> Ikev2Configurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode)
{
Q_UNUSED(containerConfig)
Q_UNUSED(protocolConfig)
// IKEv2 uses a generic ProtocolConfig - no specific subclass needed
if (!protocolConfig) {
errorCode = ErrorCode::InternalError;
return nullptr;
}
ConnectionData connData = prepareIkev2Config(credentials, container, errorCode);
if (errorCode != ErrorCode::NoError) {
return "";
return nullptr;
}
return genIkev2Config(connData);
auto ikev2Config = qSharedPointerCast<Ikev2ProtocolConfig>(protocolConfig);
if (!ikev2Config) {
errorCode = ErrorCode::InternalError;
return nullptr;
}
ikev2Config->clientProtocolConfig.isEmpty = false;
ikev2Config->clientProtocolConfig.hostName = connData.host;
ikev2Config->clientProtocolConfig.userName = connData.clientId;
ikev2Config->clientProtocolConfig.cert = QString(connData.clientCert.toBase64());
ikev2Config->clientProtocolConfig.password = connData.password;
// Generate the appropriate native config based on platform
QString nativeConfigStr;
switch (Utils::systemType()) {
case SystemType::iOS:
[[fallthrough]];
case SystemType::macOS:
nativeConfigStr = genMobileConfig(connData);
break;
case SystemType::Android:
nativeConfigStr = genIkev2Config(connData);
break;
default:
nativeConfigStr = genStrongSwanConfig(connData);
break;
}
ikev2Config->clientProtocolConfig.nativeConfig = nativeConfigStr;
return ikev2Config;
}
QString Ikev2Configurator::genIkev2Config(const ConnectionData &connData)
{
// Create temporary JSON for Android platform (will be eliminated when android protocols are updated)
QJsonObject config;
config[config_key::hostName] = connData.host;
config[config_key::userName] = connData.clientId;

View File

@@ -5,6 +5,8 @@
#include <QProcessEnvironment>
#include "configurator_base.h"
#include "core/models/protocols/protocolConfig.h"
#include "core/models/protocols/ikev2ProtocolConfig.h"
#include "core/defs.h"
class Ikev2Configurator : public ConfiguratorBase
@@ -21,13 +23,16 @@ public:
QString host; // host ip
};
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode);
QSharedPointer<ProtocolConfig> createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode) override;
QString genIkev2Config(const ConnectionData &connData);
QString genMobileConfig(const ConnectionData &connData);
QString genStrongSwanConfig(const ConnectionData &connData);
Vars generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const override;
ConnectionData prepareIkev2Config(const ServerCredentials &credentials,
DockerContainer container, ErrorCode &errorCode);
};

View File

@@ -17,6 +17,8 @@
#include "core/models/containers/containers_defs.h"
#include "core/controllers/selfhosted/serverController.h"
#include "core/scripts_registry.h"
#include "core/models/protocols/openvpnProtocolConfig.h"
#include "protocols/protocols_defs.h"
#include "settings.h"
#include "utilities.h"
@@ -31,6 +33,39 @@ OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr<Settings> settings, con
{
}
ConfiguratorBase::Vars OpenVpnConfigurator::generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const
{
Vars vars = generateCommonVars(credentials, container);
auto openVpnConfig = qSharedPointerCast<OpenVpnProtocolConfig>(protocolConfig);
if (!openVpnConfig) {
return vars;
}
vars.append({{"$OPENVPN_SUBNET_IP", openVpnConfig->serverProtocolConfig.subnetAddress}});
vars.append({{"$OPENVPN_SUBNET_CIDR", protocols::openvpn::defaultSubnetCidr}});
vars.append({{"$OPENVPN_SUBNET_MASK", protocols::openvpn::defaultSubnetMask}});
vars.append({{"$OPENVPN_PORT", openVpnConfig->serverProtocolConfig.port}});
vars.append({{"$OPENVPN_TRANSPORT_PROTO", openVpnConfig->serverProtocolConfig.transportProto}});
vars.append({{"$OPENVPN_NCP_DISABLE", openVpnConfig->serverProtocolConfig.ncpDisable ? protocols::openvpn::ncpDisableString : ""}});
vars.append({{"$OPENVPN_CIPHER", openVpnConfig->serverProtocolConfig.cipher}});
vars.append({{"$OPENVPN_HASH", openVpnConfig->serverProtocolConfig.hash}});
vars.append({{"$OPENVPN_TLS_AUTH", openVpnConfig->serverProtocolConfig.tlsAuth ? protocols::openvpn::tlsAuthString : ""}});
if (!openVpnConfig->serverProtocolConfig.tlsAuth) {
vars.append({{"$OPENVPN_TA_KEY", ""}});
}
vars.append({{"$OPENVPN_ADDITIONAL_CLIENT_CONFIG", openVpnConfig->serverProtocolConfig.additionalClientConfig}});
vars.append({{"$OPENVPN_ADDITIONAL_SERVER_CONFIG", openVpnConfig->serverProtocolConfig.additionalServerConfig}});
return vars;
}
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials,
DockerContainer container, ErrorCode &errorCode)
{
@@ -72,15 +107,21 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
return connData;
}
QString OpenVpnConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode)
QSharedPointer<ProtocolConfig> OpenVpnConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode)
{
auto openVpnConfig = qSharedPointerCast<OpenVpnProtocolConfig>(protocolConfig);
if (!openVpnConfig) {
errorCode = ErrorCode::InternalError;
return nullptr;
}
QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::openvpn_template, container),
m_serverController->genVarsForScript(credentials, container, containerConfig));
generateProtocolVars(credentials, container, protocolConfig));
ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode);
if (errorCode != ErrorCode::NoError) {
return "";
return nullptr;
}
config.replace("$OPENVPN_CA_CERT", connData.caCert);
@@ -98,12 +139,11 @@ QString OpenVpnConfigurator::createConfig(const ServerCredentials &credentials,
config.replace("block-outside-dns", "");
#endif
QJsonObject jConfig;
jConfig[config_key::config] = config;
openVpnConfig->clientProtocolConfig.isEmpty = false;
openVpnConfig->clientProtocolConfig.clientId = connData.clientId;
openVpnConfig->clientProtocolConfig.nativeConfig = config;
jConfig[config_key::clientId] = connData.clientId;
return QJsonDocument(jConfig).toJson();
return openVpnConfig;
}
QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
@@ -199,7 +239,7 @@ ErrorCode OpenVpnConfigurator::signCert(DockerContainer container, const ServerC
.arg(clientId);
QStringList scriptList { script_import, script_sign };
QString script = m_serverController->replaceVars(scriptList.join("\n"), m_serverController->genVarsForScript(credentials, container));
QString script = m_serverController->replaceVars(scriptList.join("\n"), generateProtocolVars(credentials, container));
return m_serverController->runScript(credentials, script);
}

View File

@@ -6,6 +6,7 @@
#include "configurator_base.h"
#include "core/defs.h"
#include "core/models/protocols/openvpnProtocolConfig.h"
class OpenVpnConfigurator : public ConfiguratorBase
{
@@ -24,14 +25,17 @@ public:
QString host; // host ip
};
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode);
QSharedPointer<ProtocolConfig> createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode) override;
QString processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
QString &protocolConfigString);
QString processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
QString &protocolConfigString);
Vars generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const override;
static ConnectionData createCertRequest();
private:

View File

@@ -6,6 +6,8 @@
#include "core/models/containers/containers_defs.h"
#include "core/controllers/selfhosted/serverController.h"
#include "core/models/protocols/shadowsocksProtocolConfig.h"
#include "protocols/protocols_defs.h"
ShadowSocksConfigurator::ShadowSocksConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController,
QObject *parent)
@@ -13,28 +15,59 @@ ShadowSocksConfigurator::ShadowSocksConfigurator(std::shared_ptr<Settings> setti
{
}
QString ShadowSocksConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode)
ConfiguratorBase::Vars ShadowSocksConfigurator::generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const
{
Vars vars = generateCommonVars(credentials, container);
auto shadowsocksConfig = qSharedPointerCast<ShadowsocksProtocolConfig>(protocolConfig);
if (!shadowsocksConfig) {
return vars;
}
vars.append({{"$SHADOWSOCKS_SERVER_PORT", shadowsocksConfig->serverProtocolConfig.port}});
vars.append({{"$SHADOWSOCKS_LOCAL_PORT", protocols::shadowsocks::defaultLocalProxyPort}});
vars.append({{"$SHADOWSOCKS_CIPHER", shadowsocksConfig->serverProtocolConfig.cipher}});
return vars;
}
QSharedPointer<ProtocolConfig> ShadowSocksConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode)
{
auto shadowsocksConfig = qSharedPointerCast<ShadowsocksProtocolConfig>(protocolConfig);
if (!shadowsocksConfig) {
errorCode = ErrorCode::InternalError;
return nullptr;
}
QString ssKey =
m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::shadowsocks::ssKeyPath, errorCode);
ssKey.replace("\n", "");
if (errorCode != ErrorCode::NoError) {
return "";
return nullptr;
}
shadowsocksConfig->clientProtocolConfig.server = credentials.hostName;
shadowsocksConfig->clientProtocolConfig.serverPort = shadowsocksConfig->serverProtocolConfig.port;
shadowsocksConfig->clientProtocolConfig.localPort = protocols::shadowsocks::defaultLocalProxyPort;
shadowsocksConfig->clientProtocolConfig.password = ssKey;
shadowsocksConfig->clientProtocolConfig.timeout = 60;
shadowsocksConfig->clientProtocolConfig.method = shadowsocksConfig->serverProtocolConfig.cipher;
QJsonObject config;
config.insert("server", credentials.hostName);
config.insert("server_port", "$SHADOWSOCKS_SERVER_PORT");
config.insert("local_port", "$SHADOWSOCKS_LOCAL_PORT");
config.insert("password", ssKey);
config.insert("timeout", 60);
config.insert("method", "$SHADOWSOCKS_CIPHER");
config.insert("server", shadowsocksConfig->clientProtocolConfig.server);
config.insert("server_port", shadowsocksConfig->clientProtocolConfig.serverPort);
config.insert("local_port", shadowsocksConfig->clientProtocolConfig.localPort);
config.insert("password", shadowsocksConfig->clientProtocolConfig.password);
config.insert("timeout", shadowsocksConfig->clientProtocolConfig.timeout);
config.insert("method", shadowsocksConfig->clientProtocolConfig.method);
QString textCfg = m_serverController->replaceVars(QJsonDocument(config).toJson(),
m_serverController->genVarsForScript(credentials, container, containerConfig));
QString textCfg = QJsonDocument(config).toJson();
// qDebug().noquote() << textCfg;
return textCfg;
shadowsocksConfig->clientProtocolConfig.isEmpty = false;
shadowsocksConfig->clientProtocolConfig.nativeConfig = textCfg;
return shadowsocksConfig;
}

View File

@@ -4,6 +4,7 @@
#include <QObject>
#include "configurator_base.h"
#include "core/models/protocols/shadowsocksProtocolConfig.h"
#include "core/defs.h"
class ShadowSocksConfigurator : public ConfiguratorBase
@@ -12,8 +13,11 @@ class ShadowSocksConfigurator : public ConfiguratorBase
public:
ShadowSocksConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode);
QSharedPointer<ProtocolConfig> createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode) override;
Vars generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const override;
};
#endif // SHADOWSOCKS_CONFIGURATOR_H

View File

@@ -7,6 +7,8 @@
#include <QString>
#include <QTemporaryDir>
#include <QTemporaryFile>
#include <type_traits>
#include <variant>
#include <openssl/pem.h>
#include <openssl/rand.h>
@@ -17,6 +19,9 @@
#include "core/controllers/selfhosted/serverController.h"
#include "core/scripts_registry.h"
#include "core/server_defs.h"
#include "core/models/protocols/wireguardProtocolConfig.h"
#include "core/models/protocols/awgProtocolConfig.h"
#include "protocols/protocols_defs.h"
#include "settings.h"
#include "utilities.h"
@@ -37,6 +42,47 @@ WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings,
m_defaultPort = m_isAwg ? protocols::wireguard::defaultPort : protocols::awg::defaultPort;
}
ConfiguratorBase::Vars WireguardConfigurator::generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const
{
Vars vars = generateCommonVars(credentials, container);
if (m_isAwg) {
auto awgConfig = qSharedPointerCast<AwgProtocolConfig>(protocolConfig);
if (!awgConfig) {
return vars;
}
vars.append({{"$AWG_SUBNET_IP", awgConfig->serverProtocolConfig.subnetAddress}});
vars.append({{"$AWG_SERVER_PORT", awgConfig->serverProtocolConfig.port}});
const auto &awgData = awgConfig->serverProtocolConfig.awgData;
vars.append({{"$JUNK_PACKET_COUNT", awgData.junkPacketCount}});
vars.append({{"$JUNK_PACKET_MIN_SIZE", awgData.junkPacketMinSize}});
vars.append({{"$JUNK_PACKET_MAX_SIZE", awgData.junkPacketMaxSize}});
vars.append({{"$INIT_PACKET_JUNK_SIZE", awgData.initPacketJunkSize}});
vars.append({{"$RESPONSE_PACKET_JUNK_SIZE", awgData.responsePacketJunkSize}});
vars.append({{"$INIT_PACKET_MAGIC_HEADER", awgData.initPacketMagicHeader}});
vars.append({{"$RESPONSE_PACKET_MAGIC_HEADER", awgData.responsePacketMagicHeader}});
vars.append({{"$UNDERLOAD_PACKET_MAGIC_HEADER", awgData.underloadPacketMagicHeader}});
vars.append({{"$TRANSPORT_PACKET_MAGIC_HEADER", awgData.transportPacketMagicHeader}});
vars.append({{"$COOKIE_REPLY_PACKET_JUNK_SIZE", awgData.cookieReplyPacketJunkSize}});
vars.append({{"$TRANSPORT_PACKET_JUNK_SIZE", awgData.transportPacketJunkSize}});
} else {
auto wgConfig = qSharedPointerCast<WireGuardProtocolConfig>(protocolConfig);
if (!wgConfig) {
return vars;
}
vars.append({{"$WIREGUARD_SUBNET_IP", wgConfig->serverProtocolConfig.subnetAddress}});
vars.append({{"$WIREGUARD_SUBNET_CIDR", protocols::wireguard::defaultSubnetCidr}});
vars.append({{"$WIREGUARD_SUBNET_MASK", protocols::wireguard::defaultSubnetMask}});
vars.append({{"$WIREGUARD_SERVER_PORT", wgConfig->serverProtocolConfig.port}});
}
return vars;
}
WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
{
// TODO review
@@ -91,12 +137,20 @@ QList<QHostAddress> WireguardConfigurator::getIpsFromConf(const QString &input)
WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardConfig(const ServerCredentials &credentials,
DockerContainer container,
const QJsonObject &containerConfig,
const QSharedPointer<ProtocolConfig> &protocolConfig,
ErrorCode &errorCode)
{
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
connData.host = credentials.hostName;
connData.port = containerConfig.value(m_protocolName).toObject().value(config_key::port).toString(m_defaultPort);
// Extract port from appropriate protocol config
if (m_isAwg) {
auto awgConfig = qSharedPointerCast<AwgProtocolConfig>(protocolConfig);
connData.port = awgConfig ? awgConfig->serverProtocolConfig.port : m_defaultPort;
} else {
auto wgConfig = qSharedPointerCast<WireGuardProtocolConfig>(protocolConfig);
connData.port = wgConfig ? wgConfig->serverProtocolConfig.port : m_defaultPort;
}
if (connData.clientPrivKey.isEmpty() || connData.clientPubKey.isEmpty()) {
errorCode = ErrorCode::InternalError;
@@ -120,10 +174,16 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
QHostAddress result;
QHostAddress lastIp;
if (ips.empty()) {
lastIp.setAddress(containerConfig.value(m_protocolName)
.toObject()
.value(config_key::subnet_address)
.toString(protocols::wireguard::defaultSubnetAddress));
// Get subnet from protocol config
QString subnetAddress;
if (m_isAwg) {
auto awgConfig = qSharedPointerCast<AwgProtocolConfig>(protocolConfig);
subnetAddress = awgConfig ? awgConfig->serverProtocolConfig.subnetAddress : protocols::wireguard::defaultSubnetAddress;
} else {
auto wgConfig = qSharedPointerCast<WireGuardProtocolConfig>(protocolConfig);
subnetAddress = wgConfig ? wgConfig->serverProtocolConfig.subnetAddress : protocols::wireguard::defaultSubnetAddress;
}
lastIp.setAddress(subnetAddress);
} else {
lastIp = ips.last();
}
@@ -173,21 +233,39 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
errorCode = m_serverController->runScript(
credentials,
m_serverController->replaceVars(script, m_serverController->genVarsForScript(credentials, container)));
m_serverController->replaceVars(script, generateProtocolVars(credentials, container)));
return connData;
}
QString WireguardConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode)
QSharedPointer<ProtocolConfig> WireguardConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode)
{
QSharedPointer<ProtocolConfig> result;
if (m_isAwg) {
auto awgConfig = qSharedPointerCast<AwgProtocolConfig>(protocolConfig);
if (!awgConfig) {
errorCode = ErrorCode::InternalError;
return nullptr;
}
result = awgConfig;
} else {
auto wgConfig = qSharedPointerCast<WireGuardProtocolConfig>(protocolConfig);
if (!wgConfig) {
errorCode = ErrorCode::InternalError;
return nullptr;
}
result = wgConfig;
}
QString scriptData = amnezia::scriptData(m_configTemplate, container);
QString config = m_serverController->replaceVars(
scriptData, m_serverController->genVarsForScript(credentials, container, containerConfig));
scriptData, generateProtocolVars(credentials, container, protocolConfig));
ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode);
ConnectionData connData = prepareWireguardConfig(credentials, container, protocolConfig, errorCode);
if (errorCode != ErrorCode::NoError) {
return "";
return nullptr;
}
config.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", connData.clientPrivKey);
@@ -195,26 +273,27 @@ QString WireguardConfigurator::createConfig(const ServerCredentials &credentials
config.replace("$WIREGUARD_SERVER_PUBLIC_KEY", connData.serverPubKey);
config.replace("$WIREGUARD_PSK", connData.pskKey);
const QJsonObject &wireguarConfig = containerConfig.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject();
QJsonObject jConfig;
jConfig[config_key::config] = config;
ProtocolConfigVariant variant = ProtocolConfig::getProtocolConfigVariant(result);
std::visit([&connData, &config](const auto &protocolConfig) -> void {
using ConfigType = std::decay_t<decltype(*protocolConfig)>;
if constexpr (std::is_same_v<ConfigType, AwgProtocolConfig> || std::is_same_v<ConfigType, WireGuardProtocolConfig>) {
protocolConfig->clientProtocolConfig.isEmpty = false;
protocolConfig->clientProtocolConfig.clientId = connData.clientPubKey;
protocolConfig->clientProtocolConfig.hostname = connData.host;
protocolConfig->clientProtocolConfig.port = connData.port.toInt();
protocolConfig->clientProtocolConfig.wireGuardData.clientPrivateKey = connData.clientPrivKey;
protocolConfig->clientProtocolConfig.wireGuardData.clientIp = connData.clientIP;
protocolConfig->clientProtocolConfig.wireGuardData.clientPublicKey = connData.clientPubKey;
protocolConfig->clientProtocolConfig.wireGuardData.pskKey = connData.pskKey;
protocolConfig->clientProtocolConfig.wireGuardData.serverPubKey = connData.serverPubKey;
protocolConfig->clientProtocolConfig.wireGuardData.mtu = protocolConfig->serverProtocolConfig.mtu;
protocolConfig->clientProtocolConfig.wireGuardData.persistentKeepAlive = "25";
protocolConfig->clientProtocolConfig.wireGuardData.allowedIps = QStringList{"0.0.0.0/0", "::/0"};
protocolConfig->clientProtocolConfig.nativeConfig = config;
}
}, variant);
jConfig[config_key::hostName] = connData.host;
jConfig[config_key::port] = connData.port.toInt();
jConfig[config_key::client_priv_key] = connData.clientPrivKey;
jConfig[config_key::client_ip] = connData.clientIP;
jConfig[config_key::client_pub_key] = connData.clientPubKey;
jConfig[config_key::psk_key] = connData.pskKey;
jConfig[config_key::server_pub_key] = connData.serverPubKey;
jConfig[config_key::mtu] = wireguarConfig.value(config_key::mtu).toString(protocols::wireguard::defaultMtu);
jConfig[config_key::persistent_keep_alive] = "25";
QJsonArray allowedIps { "0.0.0.0/0", "::/0" };
jConfig[config_key::allowed_ips] = allowedIps;
jConfig[config_key::clientId] = connData.clientPubKey;
return QJsonDocument(jConfig).toJson();
return result;
}
QString WireguardConfigurator::processConfigWithLocalSettings(const QPair<QString, QString> &dns,

View File

@@ -6,6 +6,8 @@
#include <QProcessEnvironment>
#include "configurator_base.h"
#include "core/models/protocols/wireguardProtocolConfig.h"
#include "core/models/protocols/awgProtocolConfig.h"
#include "core/defs.h"
#include "core/scripts_registry.h"
@@ -27,20 +29,23 @@ public:
QString port;
};
QString createConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode);
QSharedPointer<ProtocolConfig> createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode) override;
QString processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
QString &protocolConfigString);
QString processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
QString &protocolConfigString);
Vars generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const override;
static ConnectionData genClientKeys();
private:
QList<QHostAddress> getIpsFromConf(const QString &input);
ConnectionData prepareWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode);
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode);
bool m_isAwg;
QString m_serverConfigPath;

View File

@@ -9,6 +9,8 @@
#include "core/models/containers/containers_defs.h"
#include "core/controllers/selfhosted/serverController.h"
#include "core/scripts_registry.h"
#include "core/models/protocols/xrayProtocolConfig.h"
#include "protocols/protocols_defs.h"
namespace {
Logger logger("XrayConfigurator");
@@ -19,8 +21,24 @@ XrayConfigurator::XrayConfigurator(std::shared_ptr<Settings> settings, const QSh
{
}
ConfiguratorBase::Vars XrayConfigurator::generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const
{
Vars vars = generateCommonVars(credentials, container);
auto xrayConfig = qSharedPointerCast<XrayProtocolConfig>(protocolConfig);
if (!xrayConfig) {
return vars;
}
vars.append({{"$XRAY_SITE_NAME", xrayConfig->serverProtocolConfig.site}});
vars.append({{"$XRAY_SERVER_PORT", xrayConfig->serverProtocolConfig.port}});
return vars;
}
QString XrayConfigurator::prepareServerConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode)
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode)
{
// Generate new UUID for client
QString clientId = QUuid::createUuid().toString(QUuid::WithoutBraces);
@@ -44,7 +62,6 @@ QString XrayConfigurator::prepareServerConfig(const ServerCredentials &credentia
QJsonObject serverConfig = doc.object();
// Validate server config structure
if (!serverConfig.contains("inbounds")) {
logger.error() << "Server config missing 'inbounds' field";
errorCode = ErrorCode::InternalError;
@@ -106,7 +123,7 @@ QString XrayConfigurator::prepareServerConfig(const ServerCredentials &credentia
QString restartScript = QString("sudo docker restart $CONTAINER_NAME");
errorCode = m_serverController->runScript(
credentials,
m_serverController->replaceVars(restartScript, m_serverController->genVarsForScript(credentials, container))
m_serverController->replaceVars(restartScript, generateProtocolVars(credentials, container))
);
if (errorCode != ErrorCode::NoError) {
@@ -117,24 +134,30 @@ QString XrayConfigurator::prepareServerConfig(const ServerCredentials &credentia
return clientId;
}
QString XrayConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode)
QSharedPointer<ProtocolConfig> XrayConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode)
{
auto xrayConfig = qSharedPointerCast<XrayProtocolConfig>(protocolConfig);
if (!xrayConfig) {
errorCode = ErrorCode::InternalError;
return nullptr;
}
// Get client ID from prepareServerConfig
QString xrayClientId = prepareServerConfig(credentials, container, containerConfig, errorCode);
QString xrayClientId = prepareServerConfig(credentials, container, protocolConfig, errorCode);
if (errorCode != ErrorCode::NoError || xrayClientId.isEmpty()) {
logger.error() << "Failed to prepare server config";
errorCode = ErrorCode::InternalError;
return "";
return nullptr;
}
QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::xray_template, container),
m_serverController->genVarsForScript(credentials, container, containerConfig));
generateProtocolVars(credentials, container, protocolConfig));
if (config.isEmpty()) {
logger.error() << "Failed to get config template";
errorCode = ErrorCode::InternalError;
return "";
return nullptr;
}
QString xrayPublicKey =
@@ -142,7 +165,7 @@ QString XrayConfigurator::createConfig(const ServerCredentials &credentials, Doc
if (errorCode != ErrorCode::NoError || xrayPublicKey.isEmpty()) {
logger.error() << "Failed to get public key";
errorCode = ErrorCode::InternalError;
return "";
return nullptr;
}
xrayPublicKey.replace("\n", "");
@@ -151,7 +174,7 @@ QString XrayConfigurator::createConfig(const ServerCredentials &credentials, Doc
if (errorCode != ErrorCode::NoError || xrayShortId.isEmpty()) {
logger.error() << "Failed to get short ID";
errorCode = ErrorCode::InternalError;
return "";
return nullptr;
}
xrayShortId.replace("\n", "");
@@ -162,12 +185,16 @@ QString XrayConfigurator::createConfig(const ServerCredentials &credentials, Doc
<< "XRAY_PUBLIC_KEY:" << !config.contains("$XRAY_PUBLIC_KEY")
<< "XRAY_SHORT_ID:" << !config.contains("$XRAY_SHORT_ID");
errorCode = ErrorCode::InternalError;
return "";
return nullptr;
}
config.replace("$XRAY_CLIENT_ID", xrayClientId);
config.replace("$XRAY_PUBLIC_KEY", xrayPublicKey);
config.replace("$XRAY_SHORT_ID", xrayShortId);
return config;
xrayConfig->clientProtocolConfig.isEmpty = false;
xrayConfig->clientProtocolConfig.clientId = xrayClientId;
xrayConfig->clientProtocolConfig.nativeConfig = config;
return xrayConfig;
}

View File

@@ -4,6 +4,7 @@
#include <QObject>
#include "configurator_base.h"
#include "core/models/protocols/xrayProtocolConfig.h"
#include "core/defs.h"
class XrayConfigurator : public ConfiguratorBase
@@ -12,12 +13,15 @@ class XrayConfigurator : public ConfiguratorBase
public:
XrayConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent = nullptr);
QString createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
ErrorCode &errorCode);
QSharedPointer<ProtocolConfig> createConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode) override;
Vars generateProtocolVars(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig) const override;
private:
QString prepareServerConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
ErrorCode &errorCode);
QString prepareServerConfig(const ServerCredentials &credentials, DockerContainer container,
const QSharedPointer<ProtocolConfig> &protocolConfig, ErrorCode &errorCode);
};
#endif // XRAY_CONFIGURATOR_H

View File

@@ -440,7 +440,7 @@ ErrorCode ClientManagementController::wgShow(const DockerContainer container, co
const QString command = QString("sudo docker exec -i $CONTAINER_NAME bash -c '%1'").arg("wg show all");
QString script = serverController->replaceVars(command, serverController->genVarsForScript(credentials, container));
QString script = serverController->replaceVars(command, serverController->generateVarsForContainer(credentials, container));
error = serverController->runScript(credentials, script, cbReadStdOut);
if (error != ErrorCode::NoError) {
logger.error() << "Failed to execute wg show command";
@@ -668,7 +668,7 @@ ErrorCode ClientManagementController::revokeOpenVpn(const int row, const DockerC
const QString revokeClientScript = "sudo docker exec -i $CONTAINER_NAME bash -c './easyrsa --batch revoke %1'";
QString script = serverController->replaceVars(revokeClientScript.arg(clientId),
serverController->genVarsForScript(credentials, container));
serverController->generateVarsForContainer(credentials, container));
error = serverController->runScript(credentials, script, cbReadStdOut);
if (error != ErrorCode::NoError) {
return error;

View File

@@ -1,109 +0,0 @@
#include "installationController.h"
#include <QtConcurrent>
#include "core/controllers/vpnConfigurationController.h"
#include "core/networkUtilities.h"
#include "settings.h"
#include "logger.h"
namespace
{
Logger logger("InstallationController");
}
InstallationController::InstallationController(std::shared_ptr<Settings> settings, QObject *parent)
: QObject(parent), m_settings(settings)
{
}
QFuture<ErrorCode> InstallationController::installContainer(const QSharedPointer<ServerConfig> &serverConfig,
DockerContainer container,
const QJsonObject &containerConfig)
{
return QtConcurrent::run([this, serverConfig, container, containerConfig]() -> ErrorCode {
// TODO: Implement container installation logic
// This will be moved from UI InstallController
logger.info() << "Installing container" << ContainerProps::containerToString(container);
return ErrorCode::NoError;
});
}
QFuture<ErrorCode> InstallationController::scanServerForInstalledContainers(const QSharedPointer<ServerConfig> &serverConfig)
{
return QtConcurrent::run([this, serverConfig]() -> ErrorCode {
// TODO: Implement server scanning logic
// This will be moved from UI InstallController
logger.info() << "Scanning server for installed containers";
return ErrorCode::NoError;
});
}
QFuture<ErrorCode> InstallationController::removeContainer(const QSharedPointer<ServerConfig> &serverConfig,
DockerContainer container)
{
return QtConcurrent::run([this, serverConfig, container]() -> ErrorCode {
// TODO: Implement container removal logic
logger.info() << "Removing container" << ContainerProps::containerToString(container);
return ErrorCode::NoError;
});
}
QFuture<ErrorCode> InstallationController::updateContainer(const QSharedPointer<ServerConfig> &serverConfig,
DockerContainer container,
const QJsonObject &containerConfig)
{
return QtConcurrent::run([this, serverConfig, container, containerConfig]() -> ErrorCode {
// TODO: Implement container update logic
logger.info() << "Updating container" << ContainerProps::containerToString(container);
return ErrorCode::NoError;
});
}
QFuture<ErrorCode> InstallationController::rebootServer(const QSharedPointer<ServerConfig> &serverConfig)
{
return QtConcurrent::run([this, serverConfig]() -> ErrorCode {
// TODO: Implement server reboot logic
logger.info() << "Rebooting server";
return ErrorCode::NoError;
});
}
QFuture<ErrorCode> InstallationController::removeAllContainers(const QSharedPointer<ServerConfig> &serverConfig)
{
return QtConcurrent::run([this, serverConfig]() -> ErrorCode {
// TODO: Implement all containers removal logic
logger.info() << "Removing all containers";
return ErrorCode::NoError;
});
}
QFuture<bool> InstallationController::checkSshConnection(const QSharedPointer<ServerConfig> &serverConfig)
{
return QtConcurrent::run([this, serverConfig]() -> bool {
// TODO: Implement SSH connection check logic
logger.info() << "Checking SSH connection";
return true;
});
}
QFuture<ErrorCode> InstallationController::mountSftpDrive(const QSharedPointer<ServerConfig> &serverConfig,
const QString &port,
const QString &password,
const QString &username)
{
return QtConcurrent::run([this, serverConfig, port, password, username]() -> ErrorCode {
// TODO: Implement SFTP mounting logic
logger.info() << "Mounting SFTP drive";
return ErrorCode::NoError;
});
}
ErrorCode InstallationController::getAlreadyInstalledContainers(const ServerCredentials &serverCredentials,
const QSharedPointer<ServerController> &serverController,
QMap<DockerContainer, QJsonObject> &installedContainers)
{
// TODO: Implement logic to get already installed containers
// This will be moved from UI InstallController
return ErrorCode::NoError;
}

View File

@@ -1,61 +0,0 @@
#ifndef INSTALLATIONCONTROLLER_H
#define INSTALLATIONCONTROLLER_H
#include <QObject>
#include <QFuture>
#include <QSharedPointer>
#include "core/defs.h"
#include "core/models/containers/containers_defs.h"
#include "core/models/servers/serverConfig.h"
#include "serverController.h"
class Settings;
using namespace amnezia;
class InstallationController : public QObject
{
Q_OBJECT
public:
explicit InstallationController(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
QFuture<ErrorCode> installContainer(const QSharedPointer<ServerConfig> &serverConfig,
DockerContainer container,
const QJsonObject &containerConfig);
QFuture<ErrorCode> scanServerForInstalledContainers(const QSharedPointer<ServerConfig> &serverConfig);
QFuture<ErrorCode> removeContainer(const QSharedPointer<ServerConfig> &serverConfig,
DockerContainer container);
QFuture<ErrorCode> updateContainer(const QSharedPointer<ServerConfig> &serverConfig,
DockerContainer container,
const QJsonObject &containerConfig);
QFuture<ErrorCode> rebootServer(const QSharedPointer<ServerConfig> &serverConfig);
QFuture<ErrorCode> removeAllContainers(const QSharedPointer<ServerConfig> &serverConfig);
QFuture<bool> checkSshConnection(const QSharedPointer<ServerConfig> &serverConfig);
QFuture<ErrorCode> mountSftpDrive(const QSharedPointer<ServerConfig> &serverConfig,
const QString &port,
const QString &password,
const QString &username);
signals:
void installationFinished(const QString &finishMessage, bool isServiceInstall);
void installationProgress(const QString &message);
void installationError(ErrorCode errorCode);
private:
ErrorCode getAlreadyInstalledContainers(const ServerCredentials &serverCredentials,
const QSharedPointer<ServerController> &serverController,
QMap<DockerContainer, QJsonObject> &installedContainers);
std::shared_ptr<Settings> m_settings;
};
#endif // INSTALLATIONCONTROLLER_H

View File

@@ -29,7 +29,15 @@
#include "logger.h"
#include "settings.h"
#include "utilities.h"
#include "vpnConfigurationController.h"
#include "configurators/awg_configurator.h"
#include "configurators/cloak_configurator.h"
#include "configurators/ikev2_configurator.h"
#include "configurators/openvpn_configurator.h"
#include "configurators/shadowsocks_configurator.h"
#include "configurators/wireguard_configurator.h"
#include "configurators/xray_configurator.h"
#include "core/models/protocols/sftpProtocolConfig.h"
#include "core/models/protocols/socks5ProtocolConfig.h"
namespace
{
@@ -106,10 +114,10 @@ ErrorCode ServerController::runContainerScript(const ServerCredentials &credenti
QString runner =
QString("sudo docker exec -i $CONTAINER_NAME %2 %1 ").arg(fileName, (container == DockerContainer::Socks5Proxy ? "sh" : "bash"));
e = runScript(credentials, replaceVars(runner, genVarsForScript(credentials, container)), cbReadStdOut, cbReadStdErr);
e = runScript(credentials, replaceVars(runner, generateVarsForContainer(credentials, container)), cbReadStdOut, cbReadStdErr);
QString remover = QString("sudo docker exec -i $CONTAINER_NAME rm %1 ").arg(fileName);
runScript(credentials, replaceVars(remover, genVarsForScript(credentials, container)), cbReadStdOut, cbReadStdErr);
runScript(credentials, replaceVars(remover, generateVarsForContainer(credentials, container)), cbReadStdOut, cbReadStdErr);
return e;
}
@@ -132,14 +140,14 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
// mkdir
QString mkdir = QString("sudo docker exec -i $CONTAINER_NAME mkdir -p \"$(dirname %1)\"").arg(path);
e = runScript(credentials, replaceVars(mkdir, genVarsForScript(credentials, container)));
e = runScript(credentials, replaceVars(mkdir, generateVarsForContainer(credentials, container)));
if (e)
return e;
if (overwriteMode == libssh::ScpOverwriteMode::ScpOverwriteExisting) {
e = runScript(credentials,
replaceVars(QStringLiteral("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName, path),
genVarsForScript(credentials, container)),
generateVarsForContainer(credentials, container)),
cbReadStd, cbReadStd);
if (e)
@@ -147,7 +155,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
} else if (overwriteMode == libssh::ScpOverwriteMode::ScpAppendToExisting) {
e = runScript(credentials,
replaceVars(QStringLiteral("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName, tmpFileName),
genVarsForScript(credentials, container)),
generateVarsForContainer(credentials, container)),
cbReadStd, cbReadStd);
if (e)
@@ -155,7 +163,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
e = runScript(credentials,
replaceVars(QStringLiteral("sudo docker exec -i $CONTAINER_NAME sh -c \"cat %1 >> %2\"").arg(tmpFileName, path),
genVarsForScript(credentials, container)),
generateVarsForContainer(credentials, container)),
cbReadStd, cbReadStd);
if (e)
@@ -167,7 +175,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
return ErrorCode::ServerContainerMissingError;
}
runScript(credentials, replaceVars(QString("sudo shred -u %1").arg(tmpFileName), genVarsForScript(credentials, container)));
runScript(credentials, replaceVars(QString("sudo shred -u %1").arg(tmpFileName), generateVarsForContainer(credentials, container)));
return e;
}
@@ -236,7 +244,7 @@ ErrorCode ServerController::removeAllContainers(const ServerCredentials &credent
ErrorCode ServerController::removeContainer(const ServerCredentials &credentials, DockerContainer container)
{
return runScript(credentials,
replaceVars(amnezia::scriptData(SharedScriptType::remove_container), genVarsForScript(credentials, container)));
replaceVars(amnezia::scriptData(SharedScriptType::remove_container), generateVarsForContainer(credentials, container)));
}
ErrorCode ServerController::setupContainer(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config, bool isUpdate)
@@ -415,7 +423,7 @@ ErrorCode ServerController::installDockerWorker(const ServerCredentials &credent
};
ErrorCode error =
runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::install_docker), genVarsForScript(credentials)),
runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::install_docker), generateVarsForContainer(credentials, DockerContainer::None)),
cbReadStdOut, cbReadStdErr);
qDebug().noquote() << "ServerController::installDockerWorker" << stdOut;
@@ -430,14 +438,14 @@ ErrorCode ServerController::installDockerWorker(const ServerCredentials &credent
ErrorCode ServerController::prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
{
// create folder on host
return runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::prepare_host), genVarsForScript(credentials, container)));
return runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::prepare_host), generateVarsForContainer(credentials, container)));
}
ErrorCode ServerController::buildContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
{
QString dockerFilePath = amnezia::server::getDockerfileFolder(container) + "/Dockerfile";
QString scriptString = QString("sudo rm %1").arg(dockerFilePath);
ErrorCode errorCode = runScript(credentials, replaceVars(scriptString, genVarsForScript(credentials, container)));
ErrorCode errorCode = runScript(credentials, replaceVars(scriptString, generateVarsForContainer(credentials, container)));
if (errorCode)
return errorCode;
@@ -458,7 +466,7 @@ ErrorCode ServerController::buildContainerWorker(const ServerCredentials &creden
ErrorCode error =
runScript(credentials,
replaceVars(amnezia::scriptData(SharedScriptType::build_container), genVarsForScript(credentials, container, config)),
replaceVars(amnezia::scriptData(SharedScriptType::build_container), generateVarsForContainer(credentials, container, config)),
cbReadStdOut, cbReadStdErr);
if (stdOut.contains("doesn't work on cgroups v2"))
@@ -481,7 +489,7 @@ ErrorCode ServerController::runContainerWorker(const ServerCredentials &credenti
ErrorCode e = runScript(credentials,
replaceVars(amnezia::scriptData(ProtocolScriptType::run_container, container),
genVarsForScript(credentials, container, config)),
generateVarsForContainer(credentials, container, config)),
cbReadStdOut);
if (stdOut.contains("address already in use"))
@@ -508,7 +516,7 @@ ErrorCode ServerController::configureContainerWorker(const ServerCredentials &cr
ErrorCode e = runContainerScript(credentials, container,
replaceVars(amnezia::scriptData(ProtocolScriptType::configure_container, container),
genVarsForScript(credentials, container, config)),
generateVarsForContainer(credentials, container, config)),
cbReadStdOut, cbReadStdErr);
VpnConfigurationsController::updateContainerConfigAfterInstallation(container, config, stdOut);
@@ -524,7 +532,7 @@ ErrorCode ServerController::startupContainerWorker(const ServerCredentials &cred
return ErrorCode::NoError;
}
ErrorCode e = uploadTextFileToContainer(container, credentials, replaceVars(script, genVarsForScript(credentials, container, config)),
ErrorCode e = uploadTextFileToContainer(container, credentials, replaceVars(script, generateVarsForContainer(credentials, container, config)),
"/opt/amnezia/start.sh");
if (e)
return e;
@@ -532,138 +540,99 @@ ErrorCode ServerController::startupContainerWorker(const ServerCredentials &cred
return runScript(credentials,
replaceVars("sudo docker exec -d $CONTAINER_NAME sh -c \"chmod a+x /opt/amnezia/start.sh && "
"/opt/amnezia/start.sh\"",
genVarsForScript(credentials, container, config)));
generateVarsForContainer(credentials, container, config)));
}
ServerController::Vars ServerController::genVarsForScript(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &config)
ServerController::Vars ServerController::generateVarsForContainer(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &config)
{
const QJsonObject &openvpnConfig = config.value(ProtocolProps::protoToString(Proto::OpenVpn)).toObject();
const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Proto::Cloak)).toObject();
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Proto::ShadowSocks)).toObject();
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject();
const QJsonObject &amneziaWireguarConfig = config.value(ProtocolProps::protoToString(Proto::Awg)).toObject();
const QJsonObject &xrayConfig = config.value(ProtocolProps::protoToString(Proto::Xray)).toObject();
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Proto::Sftp)).toObject();
const QJsonObject &socks5ProxyConfig = config.value(ProtocolProps::protoToString(Proto::Socks5Proxy)).toObject();
Vars vars;
vars.append({ { "$REMOTE_HOST", credentials.hostName } });
// OpenVPN vars
vars.append({ { "$OPENVPN_SUBNET_IP",
openvpnConfig.value(config_key::subnet_address).toString(protocols::openvpn::defaultSubnetAddress) } });
vars.append({ { "$OPENVPN_SUBNET_CIDR", openvpnConfig.value(config_key::subnet_cidr).toString(protocols::openvpn::defaultSubnetCidr) } });
vars.append({ { "$OPENVPN_SUBNET_MASK", openvpnConfig.value(config_key::subnet_mask).toString(protocols::openvpn::defaultSubnetMask) } });
vars.append({ { "$OPENVPN_PORT", openvpnConfig.value(config_key::port).toString(protocols::openvpn::defaultPort) } });
vars.append({ { "$OPENVPN_TRANSPORT_PROTO",
openvpnConfig.value(config_key::transport_proto).toString(protocols::openvpn::defaultTransportProto) } });
bool isNcpDisabled = openvpnConfig.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable);
vars.append({ { "$OPENVPN_NCP_DISABLE", isNcpDisabled ? protocols::openvpn::ncpDisableString : "" } });
vars.append({ { "$OPENVPN_CIPHER", openvpnConfig.value(config_key::cipher).toString(protocols::openvpn::defaultCipher) } });
vars.append({ { "$OPENVPN_HASH", openvpnConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash) } });
bool isTlsAuth = openvpnConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth);
vars.append({ { "$OPENVPN_TLS_AUTH", isTlsAuth ? protocols::openvpn::tlsAuthString : "" } });
if (!isTlsAuth) {
// erase $OPENVPN_TA_KEY, so it will not set in OpenVpnConfigurator::genOpenVpnConfig
vars.append({ { "$OPENVPN_TA_KEY", "" } });
// For VPN containers, use configurator pattern
if (ContainerProps::containerService(container) != ServiceType::Other) {
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
QScopedPointer<ConfiguratorBase> configurator;
// Create the appropriate configurator for this protocol
switch (protocol) {
case Proto::OpenVpn:
configurator.reset(new OpenVpnConfigurator(m_settings, QSharedPointer<ServerController>(this, [](ServerController*){})));
break;
case Proto::ShadowSocks:
configurator.reset(new ShadowSocksConfigurator(m_settings, QSharedPointer<ServerController>(this, [](ServerController*){})));
break;
case Proto::Cloak:
configurator.reset(new CloakConfigurator(m_settings, QSharedPointer<ServerController>(this, [](ServerController*){})));
break;
case Proto::WireGuard:
configurator.reset(new WireguardConfigurator(m_settings, QSharedPointer<ServerController>(this, [](ServerController*){}), false));
break;
case Proto::Awg:
configurator.reset(new AwgConfigurator(m_settings, QSharedPointer<ServerController>(this, [](ServerController*){})));
break;
case Proto::Ikev2:
configurator.reset(new Ikev2Configurator(m_settings, QSharedPointer<ServerController>(this, [](ServerController*){})));
break;
case Proto::Xray:
case Proto::SSXray:
configurator.reset(new XrayConfigurator(m_settings, QSharedPointer<ServerController>(this, [](ServerController*){})));
break;
default:
continue;
}
if (configurator) {
return configurator->generateProtocolVars(credentials, container, config);
}
}
}
vars.append({ { "$OPENVPN_ADDITIONAL_CLIENT_CONFIG",
openvpnConfig.value(config_key::additional_client_config).toString(protocols::openvpn::defaultAdditionalClientConfig) } });
vars.append({ { "$OPENVPN_ADDITIONAL_SERVER_CONFIG",
openvpnConfig.value(config_key::additional_server_config).toString(protocols::openvpn::defaultAdditionalServerConfig) } });
// ShadowSocks vars
vars.append({ { "$SHADOWSOCKS_SERVER_PORT", ssConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort) } });
vars.append({ { "$SHADOWSOCKS_LOCAL_PORT",
ssConfig.value(config_key::local_port).toString(protocols::shadowsocks::defaultLocalProxyPort) } });
vars.append({ { "$SHADOWSOCKS_CIPHER", ssConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher) } });
vars.append({ { "$CONTAINER_NAME", ContainerProps::containerToString(container) } });
vars.append({ { "$DOCKERFILE_FOLDER", "/opt/amnezia/" + ContainerProps::containerToString(container) } });
// Cloak vars
vars.append({ { "$CLOAK_SERVER_PORT", cloakConfig.value(config_key::port).toString(protocols::cloak::defaultPort) } });
vars.append({ { "$FAKE_WEB_SITE_ADDRESS", cloakConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite) } });
// Xray vars
vars.append({ { "$XRAY_SITE_NAME", xrayConfig.value(config_key::site).toString(protocols::xray::defaultSite) } });
vars.append({ { "$XRAY_SERVER_PORT", xrayConfig.value(config_key::port).toString(protocols::xray::defaultPort) } });
// Wireguard vars
vars.append({ { "$WIREGUARD_SUBNET_IP",
wireguarConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) } });
vars.append({ { "$WIREGUARD_SUBNET_CIDR",
wireguarConfig.value(config_key::subnet_cidr).toString(protocols::wireguard::defaultSubnetCidr) } });
vars.append({ { "$WIREGUARD_SUBNET_MASK",
wireguarConfig.value(config_key::subnet_mask).toString(protocols::wireguard::defaultSubnetMask) } });
vars.append({ { "$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) } });
// IPsec vars
vars.append({ { "$IPSEC_VPN_L2TP_NET", "192.168.42.0/24" } });
vars.append({ { "$IPSEC_VPN_L2TP_POOL", "192.168.42.10-192.168.42.250" } });
vars.append({ { "$IPSEC_VPN_L2TP_LOCAL", "192.168.42.1" } });
vars.append({ { "$IPSEC_VPN_XAUTH_NET", "192.168.43.0/24" } });
vars.append({ { "$IPSEC_VPN_XAUTH_POOL", "192.168.43.10-192.168.43.250" } });
vars.append({ { "$IPSEC_VPN_SHA2_TRUNCBUG", "yes" } });
vars.append({ { "$IPSEC_VPN_VPN_ANDROID_MTU_FIX", "yes" } });
vars.append({ { "$IPSEC_VPN_DISABLE_IKEV2", "no" } });
vars.append({ { "$IPSEC_VPN_DISABLE_L2TP", "no" } });
vars.append({ { "$IPSEC_VPN_DISABLE_XAUTH", "no" } });
vars.append({ { "$IPSEC_VPN_C2C_TRAFFIC", "no" } });
vars.append({ { "$PRIMARY_SERVER_DNS", m_settings->primaryDns() } });
vars.append({ { "$SECONDARY_SERVER_DNS", m_settings->secondaryDns() } });
// Sftp vars
vars.append({ { "$SFTP_PORT", sftpConfig.value(config_key::port).toString(QString::number(ProtocolProps::defaultPort(Proto::Sftp))) } });
vars.append({ { "$SFTP_USER", sftpConfig.value(config_key::userName).toString() } });
vars.append({ { "$SFTP_PASSWORD", sftpConfig.value(config_key::password).toString() } });
// Amnezia wireguard vars
vars.append({ { "$AWG_SUBNET_IP",
amneziaWireguarConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) } });
vars.append({ { "$AWG_SERVER_PORT", amneziaWireguarConfig.value(config_key::port).toString(protocols::awg::defaultPort) } });
vars.append({ { "$JUNK_PACKET_COUNT", amneziaWireguarConfig.value(config_key::junkPacketCount).toString() } });
vars.append({ { "$JUNK_PACKET_MIN_SIZE", amneziaWireguarConfig.value(config_key::junkPacketMinSize).toString() } });
vars.append({ { "$JUNK_PACKET_MAX_SIZE", amneziaWireguarConfig.value(config_key::junkPacketMaxSize).toString() } });
vars.append({ { "$INIT_PACKET_JUNK_SIZE", amneziaWireguarConfig.value(config_key::initPacketJunkSize).toString() } });
vars.append({ { "$RESPONSE_PACKET_JUNK_SIZE", amneziaWireguarConfig.value(config_key::responsePacketJunkSize).toString() } });
vars.append({ { "$INIT_PACKET_MAGIC_HEADER", amneziaWireguarConfig.value(config_key::initPacketMagicHeader).toString() } });
vars.append({ { "$RESPONSE_PACKET_MAGIC_HEADER", amneziaWireguarConfig.value(config_key::responsePacketMagicHeader).toString() } });
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();
auto password = socks5ProxyConfig.value(config_key::password).toString();
QString socks5user = (!username.isEmpty() && !password.isEmpty()) ? QString("users %1:CL:%2").arg(username, password) : "";
vars.append({ { "$SOCKS5_USER", socks5user } });
vars.append({ { "$SOCKS5_AUTH_TYPE", socks5user.isEmpty() ? "none" : "strong" } });
// Handle non-VPN services (SFTP, Socks5) with direct variable generation
Vars vars;
// Common variables that apply to all containers
vars.append({{"$REMOTE_HOST", credentials.hostName}});
vars.append({{"$CONTAINER_NAME", ContainerProps::containerToString(container)}});
vars.append({{"$DOCKERFILE_FOLDER", "/opt/amnezia/" + ContainerProps::containerToString(container)}});
vars.append({{"$PRIMARY_SERVER_DNS", m_settings->primaryDns()}});
vars.append({{"$SECONDARY_SERVER_DNS", m_settings->secondaryDns()}});
QString serverIp = (container != DockerContainer::Awg && container != DockerContainer::WireGuard && container != DockerContainer::Xray)
? NetworkUtilities::getIPAddress(credentials.hostName)
: credentials.hostName;
if (!serverIp.isEmpty()) {
vars.append({ { "$SERVER_IP_ADDRESS", serverIp } });
} else {
qWarning() << "ServerController::genVarsForScript unable to resolve address for credentials.hostName";
vars.append({{"$SERVER_IP_ADDRESS", serverIp}});
}
// Handle container-specific variables for non-VPN services
if (container == DockerContainer::Sftp) {
SftpProtocolConfig protocolConfig(config.value(ProtocolProps::protoToString(Proto::Sftp)).toObject(),
ProtocolProps::protoToString(Proto::Sftp));
QString port = protocolConfig.serverProtocolConfig.port;
if (port.isEmpty()) {
port = QString::number(ProtocolProps::defaultPort(Proto::Sftp));
}
vars.append({{"$SFTP_PORT", port}});
vars.append({{"$SFTP_USER", protocolConfig.serverProtocolConfig.userName}});
vars.append({{"$SFTP_PASSWORD", protocolConfig.serverProtocolConfig.password}});
} else if (container == DockerContainer::Socks5Proxy) {
Socks5ProtocolConfig protocolConfig(config.value(ProtocolProps::protoToString(Proto::Socks5Proxy)).toObject(),
ProtocolProps::protoToString(Proto::Socks5Proxy));
QString port = protocolConfig.serverProtocolConfig.port;
if (port.isEmpty()) {
port = protocols::socks5Proxy::defaultPort;
}
vars.append({{"$SOCKS5_PROXY_PORT", port}});
const QString &username = protocolConfig.serverProtocolConfig.userName;
const QString &password = protocolConfig.serverProtocolConfig.password;
QString socks5user = (!username.isEmpty() && !password.isEmpty()) ? QString("users %1:CL:%2").arg(username, password) : "";
vars.append({{"$SOCKS5_USER", socks5user}});
vars.append({{"$SOCKS5_AUTH_TYPE", socks5user.isEmpty() ? "none" : "strong"}});
}
return vars;
@@ -693,7 +662,7 @@ void ServerController::cancelInstallation()
ErrorCode ServerController::setupServerFirewall(const ServerCredentials &credentials)
{
return runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::setup_host_firewall), genVarsForScript(credentials)));
return runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::setup_host_firewall), generateVarsForContainer(credentials, DockerContainer::None)));
}
QString ServerController::replaceVars(const QString &script, const Vars &vars)
@@ -746,12 +715,12 @@ ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credential
tcpProtoScript.append(" | grep LISTEN");
ErrorCode errorCode =
runScript(credentials, replaceVars(tcpProtoScript, genVarsForScript(credentials, container)), cbReadStdOut, cbReadStdErr);
runScript(credentials, replaceVars(tcpProtoScript, generateVarsForContainer(credentials, container)), cbReadStdOut, cbReadStdErr);
if (errorCode != ErrorCode::NoError) {
return errorCode;
}
errorCode = runScript(credentials, replaceVars(udpProtoScript, genVarsForScript(credentials, container)), cbReadStdOut, cbReadStdErr);
errorCode = runScript(credentials, replaceVars(udpProtoScript, generateVarsForContainer(credentials, container)), cbReadStdOut, cbReadStdErr);
if (errorCode != ErrorCode::NoError) {
return errorCode;
}
@@ -768,7 +737,7 @@ ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credential
script = script.append(" | grep LISTEN");
}
ErrorCode errorCode = runScript(credentials, replaceVars(script, genVarsForScript(credentials, container)), cbReadStdOut, cbReadStdErr);
ErrorCode errorCode = runScript(credentials, replaceVars(script, generateVarsForContainer(credentials, container)), cbReadStdOut, cbReadStdErr);
if (errorCode != ErrorCode::NoError) {
return errorCode;
}
@@ -792,7 +761,7 @@ ErrorCode ServerController::isUserInSudo(const ServerCredentials &credentials, D
};
const QString scriptData = amnezia::scriptData(SharedScriptType::check_user_in_sudo);
ErrorCode error = runScript(credentials, replaceVars(scriptData, genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr);
ErrorCode error = runScript(credentials, replaceVars(scriptData, generateVarsForContainer(credentials, DockerContainer::None)), cbReadStdOut, cbReadStdErr);
if (credentials.userName != "root" && stdOut.contains("sudo:") && !stdOut.contains("uname:") && stdOut.contains("not found"))
return ErrorCode::ServerSudoPackageIsNotPreinstalled;
@@ -830,7 +799,7 @@ ErrorCode ServerController::isServerDpkgBusy(const ServerCredentials &credential
return ErrorCode::ServerCancelInstallation;
}
stdOut.clear();
runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::check_server_is_busy), genVarsForScript(credentials)),
runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::check_server_is_busy), generateVarsForContainer(credentials, DockerContainer::None)),
cbReadStdOut, cbReadStdErr);
if (stdOut.contains("Packet manager not found"))

View File

@@ -39,8 +39,8 @@ public:
ErrorCode &errorCode);
QString replaceVars(const QString &script, const Vars &vars);
Vars genVarsForScript(const ServerCredentials &credentials, DockerContainer container = DockerContainer::None,
const QJsonObject &config = QJsonObject());
Vars generateVarsForContainer(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &config = QJsonObject());
ErrorCode runScript(const ServerCredentials &credentials, QString script,
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdOut = nullptr,

View File

@@ -7,6 +7,13 @@
#include "configurators/shadowsocks_configurator.h"
#include "configurators/wireguard_configurator.h"
#include "configurators/xray_configurator.h"
#include "core/models/protocols/awgProtocolConfig.h"
#include "core/models/protocols/cloakProtocolConfig.h"
#include "core/models/protocols/ikev2ProtocolConfig.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"
VpnConfigurationsController::VpnConfigurationsController(const std::shared_ptr<Settings> &settings,
QSharedPointer<ServerController> serverController, QObject *parent)
@@ -29,6 +36,29 @@ QScopedPointer<ConfiguratorBase> VpnConfigurationsController::createConfigurator
}
}
QSharedPointer<ProtocolConfig> VpnConfigurationsController::createProtocolConfig(const Proto protocol, const QJsonObject &protocolConfigJson)
{
switch (protocol) {
case Proto::OpenVpn:
return QSharedPointer<OpenVpnProtocolConfig>::create(protocolConfigJson, ProtocolProps::protoToString(protocol));
case Proto::ShadowSocks:
return QSharedPointer<ShadowsocksProtocolConfig>::create(protocolConfigJson, ProtocolProps::protoToString(protocol));
case Proto::Cloak:
return QSharedPointer<CloakProtocolConfig>::create(protocolConfigJson, ProtocolProps::protoToString(protocol));
case Proto::WireGuard:
return QSharedPointer<WireGuardProtocolConfig>::create(protocolConfigJson, ProtocolProps::protoToString(protocol));
case Proto::Awg:
return QSharedPointer<AwgProtocolConfig>::create(protocolConfigJson, ProtocolProps::protoToString(protocol));
case Proto::Xray:
case Proto::SSXray:
return QSharedPointer<XrayProtocolConfig>::create(protocolConfigJson, ProtocolProps::protoToString(protocol));
case Proto::Ikev2:
return QSharedPointer<Ikev2ProtocolConfig>::create(ProtocolProps::protoToString(protocol));
default:
return nullptr;
}
}
ErrorCode VpnConfigurationsController::createProtocolConfigForContainer(const ServerCredentials &credentials,
const DockerContainer container, QJsonObject &containerConfig)
{
@@ -39,16 +69,41 @@ ErrorCode VpnConfigurationsController::createProtocolConfigForContainer(const Se
}
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
QJsonObject protocolConfig = containerConfig.value(ProtocolProps::protoToString(protocol)).toObject();
QJsonObject protocolConfigJson = containerConfig.value(ProtocolProps::protoToString(protocol)).toObject();
auto configurator = createConfigurator(protocol);
QString protocolConfigString = configurator->createConfig(credentials, container, containerConfig, errorCode);
if (errorCode != ErrorCode::NoError) {
// Create ProtocolConfig from JSON
auto protocolConfig = createProtocolConfig(protocol, protocolConfigJson);
if (!protocolConfig) {
errorCode = ErrorCode::InternalError;
return errorCode;
}
protocolConfig.insert(config_key::last_config, protocolConfigString);
containerConfig.insert(ProtocolProps::protoToString(protocol), protocolConfig);
auto configurator = createConfigurator(protocol);
auto result = configurator->createConfig(credentials, container, protocolConfig, errorCode);
if (errorCode != ErrorCode::NoError || !result) {
return errorCode;
}
// Extract nativeConfig and store back in JSON for backward compatibility
QString nativeConfig;
if (auto openVpnConfig = qSharedPointerCast<OpenVpnProtocolConfig>(result)) {
nativeConfig = openVpnConfig->clientProtocolConfig.nativeConfig;
} else if (auto wgConfig = qSharedPointerCast<WireGuardProtocolConfig>(result)) {
nativeConfig = wgConfig->clientProtocolConfig.nativeConfig;
} else if (auto awgConfig = qSharedPointerCast<AwgProtocolConfig>(result)) {
nativeConfig = awgConfig->clientProtocolConfig.nativeConfig;
} else if (auto cloakConfig = qSharedPointerCast<CloakProtocolConfig>(result)) {
nativeConfig = cloakConfig->clientProtocolConfig.nativeConfig;
} else if (auto xrayConfig = qSharedPointerCast<XrayProtocolConfig>(result)) {
nativeConfig = xrayConfig->clientProtocolConfig.nativeConfig;
} else if (auto shadowsocksConfig = qSharedPointerCast<ShadowsocksProtocolConfig>(result)) {
nativeConfig = shadowsocksConfig->clientProtocolConfig.nativeConfig;
} else if (auto ikev2Config = qSharedPointerCast<Ikev2ProtocolConfig>(result)) {
nativeConfig = ikev2Config->clientProtocolConfig.nativeConfig;
}
protocolConfigJson.insert(config_key::last_config, nativeConfig);
containerConfig.insert(ProtocolProps::protoToString(protocol), protocolConfigJson);
}
return errorCode;
@@ -65,13 +120,39 @@ ErrorCode VpnConfigurationsController::createProtocolConfigString(const bool isA
return errorCode;
}
auto configurator = createConfigurator(protocol);
protocolConfigString = configurator->createConfig(credentials, container, containerConfig, errorCode);
if (errorCode != ErrorCode::NoError) {
// Create ProtocolConfig from JSON
QJsonObject protocolConfigJson = containerConfig.value(ProtocolProps::protoToString(protocol)).toObject();
auto protocolConfig = createProtocolConfig(protocol, protocolConfigJson);
if (!protocolConfig) {
errorCode = ErrorCode::InternalError;
return errorCode;
}
protocolConfigString = configurator->processConfigWithExportSettings(dns, isApiConfig, protocolConfigString);
auto configurator = createConfigurator(protocol);
auto result = configurator->createConfig(credentials, container, protocolConfig, errorCode);
if (errorCode != ErrorCode::NoError || !result) {
return errorCode;
}
// Extract nativeConfig
QString nativeConfig;
if (auto openVpnConfig = qSharedPointerCast<OpenVpnProtocolConfig>(result)) {
nativeConfig = openVpnConfig->clientProtocolConfig.nativeConfig;
} else if (auto wgConfig = qSharedPointerCast<WireGuardProtocolConfig>(result)) {
nativeConfig = wgConfig->clientProtocolConfig.nativeConfig;
} else if (auto awgConfig = qSharedPointerCast<AwgProtocolConfig>(result)) {
nativeConfig = awgConfig->clientProtocolConfig.nativeConfig;
} else if (auto cloakConfig = qSharedPointerCast<CloakProtocolConfig>(result)) {
nativeConfig = cloakConfig->clientProtocolConfig.nativeConfig;
} else if (auto xrayConfig = qSharedPointerCast<XrayProtocolConfig>(result)) {
nativeConfig = xrayConfig->clientProtocolConfig.nativeConfig;
} else if (auto shadowsocksConfig = qSharedPointerCast<ShadowsocksProtocolConfig>(result)) {
nativeConfig = shadowsocksConfig->clientProtocolConfig.nativeConfig;
} else if (auto ikev2Config = qSharedPointerCast<Ikev2ProtocolConfig>(result)) {
nativeConfig = ikev2Config->clientProtocolConfig.nativeConfig;
}
protocolConfigString = configurator->processConfigWithExportSettings(dns, isApiConfig, nativeConfig);
return errorCode;
}
@@ -143,3 +224,4 @@ void VpnConfigurationsController::updateContainerConfigAfterInstallation(const D
containerConfig.insert(ProtocolProps::protoToString(mainProto), protocol);
}
}

View File

@@ -6,6 +6,7 @@
#include "configurators/configurator_base.h"
#include "core/models/containers/containers_defs.h"
#include "core/defs.h"
#include "core/models/protocols/protocolConfig.h"
#include "settings.h"
class VpnConfigurationsController : public QObject
@@ -29,6 +30,7 @@ signals:
private:
QScopedPointer<ConfiguratorBase> createConfigurator(const Proto protocol);
QSharedPointer<ProtocolConfig> createProtocolConfig(const Proto protocol, const QJsonObject &protocolConfigJson);
std::shared_ptr<Settings> m_settings;
QSharedPointer<ServerController> m_serverController;

View File

@@ -13,19 +13,22 @@ AwgProtocolConfig::AwgProtocolConfig(const QString &protocolName) : ProtocolConf
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.port = protocolConfigObject.value(config_key::port).toString(protocols::awg::defaultPort);
serverProtocolConfig.transportProto = protocolConfigObject.value(config_key::transport_proto).toString("udp");
serverProtocolConfig.subnetAddress = protocolConfigObject.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
serverProtocolConfig.mtu = protocolConfigObject.value(config_key::mtu).toString(protocols::awg::defaultMtu);
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();
serverProtocolConfig.awgData.junkPacketCount = protocolConfigObject.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
serverProtocolConfig.awgData.junkPacketMinSize = protocolConfigObject.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize);
serverProtocolConfig.awgData.junkPacketMaxSize = protocolConfigObject.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize);
serverProtocolConfig.awgData.initPacketJunkSize = protocolConfigObject.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize);
serverProtocolConfig.awgData.responsePacketJunkSize = protocolConfigObject.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize);
serverProtocolConfig.awgData.cookieReplyPacketJunkSize = protocolConfigObject.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize);
serverProtocolConfig.awgData.transportPacketJunkSize = protocolConfigObject.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize);
serverProtocolConfig.awgData.initPacketMagicHeader = protocolConfigObject.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader);
serverProtocolConfig.awgData.responsePacketMagicHeader = protocolConfigObject.value(config_key::responsePacketMagicHeader).toString(protocols::awg::defaultResponsePacketMagicHeader);
serverProtocolConfig.awgData.underloadPacketMagicHeader = protocolConfigObject.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader);
serverProtocolConfig.awgData.transportPacketMagicHeader = protocolConfigObject.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader);
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
@@ -38,6 +41,8 @@ AwgProtocolConfig::AwgProtocolConfig(const QJsonObject &protocolConfigObject, co
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.cookieReplyPacketJunkSize = clientProtocolConfigObject.value(config_key::cookieReplyPacketJunkSize).toString();
clientProtocolConfig.awgData.transportPacketJunkSize = clientProtocolConfigObject.value(config_key::transportPacketJunkSize).toString();
clientProtocolConfig.awgData.initPacketMagicHeader = clientProtocolConfigObject.value(config_key::initPacketMagicHeader).toString();
clientProtocolConfig.awgData.responsePacketMagicHeader =
clientProtocolConfigObject.value(config_key::responsePacketMagicHeader).toString();
@@ -91,6 +96,9 @@ QJsonObject AwgProtocolConfig::toJson() const
if (!serverProtocolConfig.subnetAddress.isEmpty()) {
json[config_key::subnet_address] = serverProtocolConfig.subnetAddress;
}
if (!serverProtocolConfig.mtu.isEmpty()) {
json[config_key::mtu] = serverProtocolConfig.mtu;
}
if (!serverProtocolConfig.awgData.junkPacketCount.isEmpty()) {
json[config_key::junkPacketCount] = serverProtocolConfig.awgData.junkPacketCount;
@@ -107,6 +115,12 @@ QJsonObject AwgProtocolConfig::toJson() const
if (!serverProtocolConfig.awgData.responsePacketJunkSize.isEmpty()) {
json[config_key::responsePacketJunkSize] = serverProtocolConfig.awgData.responsePacketJunkSize;
}
if (!serverProtocolConfig.awgData.cookieReplyPacketJunkSize.isEmpty()) {
json[config_key::cookieReplyPacketJunkSize] = serverProtocolConfig.awgData.cookieReplyPacketJunkSize;
}
if (!serverProtocolConfig.awgData.transportPacketJunkSize.isEmpty()) {
json[config_key::transportPacketJunkSize] = serverProtocolConfig.awgData.transportPacketJunkSize;
}
if (!serverProtocolConfig.awgData.initPacketMagicHeader.isEmpty()) {
json[config_key::initPacketMagicHeader] = serverProtocolConfig.awgData.initPacketMagicHeader;
}

View File

@@ -17,6 +17,8 @@ namespace awg
QString initPacketJunkSize;
QString responsePacketJunkSize;
QString cookieReplyPacketJunkSize;
QString transportPacketJunkSize;
QString initPacketMagicHeader;
QString responsePacketMagicHeader;
@@ -30,6 +32,7 @@ namespace awg
QString transportProto;
QString subnetAddress;
QString mtu;
AwgData awgData;
};

View File

@@ -8,9 +8,9 @@ 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();
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString(protocols::cloak::defaultPort);
serverProtocolConfig.cipher = protocolConfigObject.value(config_key::cipher).toString(protocols::cloak::defaultCipher);
serverProtocolConfig.site = protocolConfigObject.value(config_key::site).toString(protocols::cloak::defaultRedirSite);
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {

View File

@@ -18,6 +18,20 @@ namespace cloak
struct ClientProtocolConfig
{
bool isEmpty = true;
QString transport = "direct";
QString proxyMethod = "openvpn";
QString encryptionMethod = "aes-gcm";
QString uid;
QString publicKey;
QString serverName;
int numConn = 1;
QString browserSig = "chrome";
int streamTimeout = 300;
QString remoteHost;
QString remotePort;
QString nativeConfig;
};
}

View File

@@ -0,0 +1,32 @@
#include "ikev2ProtocolConfig.h"
#include "config_key.h"
Ikev2ProtocolConfig::Ikev2ProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName)
: ProtocolConfig(protocolName)
{
Q_UNUSED(protocolConfigObject)
}
Ikev2ProtocolConfig::Ikev2ProtocolConfig(const QString &protocolName)
: ProtocolConfig(protocolName)
{
}
QJsonObject Ikev2ProtocolConfig::toJson() const
{
QJsonObject protocolConfigObject;
return protocolConfigObject;
}
bool Ikev2ProtocolConfig::hasEqualServerSettings(const Ikev2ProtocolConfig &other) const
{
Q_UNUSED(other)
return true;
}
void Ikev2ProtocolConfig::clearClientSettings()
{
clientProtocolConfig = ikev2::ClientProtocolConfig();
}

View File

@@ -0,0 +1,45 @@
#ifndef IKEV2PROTOCOLCONFIG_H
#define IKEV2PROTOCOLCONFIG_H
#include <QJsonObject>
#include <QString>
#include <QByteArray>
#include "protocolConfig.h"
namespace ikev2
{
struct ServerProtocolConfig
{
bool isEmpty = true;
};
struct ClientProtocolConfig
{
bool isEmpty = true;
QString hostName;
QString userName;
QString cert;
QString password;
QString nativeConfig;
};
}
class Ikev2ProtocolConfig : public ProtocolConfig
{
public:
Ikev2ProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName);
explicit Ikev2ProtocolConfig(const QString &protocolName);
QJsonObject toJson() const override;
bool hasEqualServerSettings(const Ikev2ProtocolConfig &other) const;
void clearClientSettings();
ikev2::ServerProtocolConfig serverProtocolConfig;
ikev2::ClientProtocolConfig clientProtocolConfig;
};
#endif // IKEV2PROTOCOLCONFIG_H

View File

@@ -8,17 +8,16 @@ 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.subnetAddress = protocolConfigObject.value(config_key::subnet_address).toString(protocols::openvpn::defaultSubnetAddress);
serverProtocolConfig.transportProto = protocolConfigObject.value(config_key::transport_proto).toString(protocols::openvpn::defaultTransportProto);
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString(protocols::openvpn::defaultPort);
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.hash = protocolConfigObject.value(config_key::hash).toString(protocols::openvpn::defaultHash);
serverProtocolConfig.cipher = protocolConfigObject.value(config_key::cipher).toString(protocols::openvpn::defaultCipher);
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();
serverProtocolConfig.blockOutsideDns = protocolConfigObject.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns);
serverProtocolConfig.additionalClientConfig = protocolConfigObject.value(config_key::additional_client_config).toString(protocols::openvpn::defaultAdditionalClientConfig);
serverProtocolConfig.additionalServerConfig = protocolConfigObject.value(config_key::additional_server_config).toString(protocols::openvpn::defaultAdditionalServerConfig);
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {

View File

@@ -11,10 +11,14 @@ class ShadowsocksProtocolConfig;
class CloakProtocolConfig;
class XrayProtocolConfig;
class AwgProtocolConfig;
class SftpProtocolConfig;
class Socks5ProtocolConfig;
class Ikev2ProtocolConfig;
using ProtocolConfigVariant =
std::variant<QSharedPointer<OpenVpnProtocolConfig>, QSharedPointer<WireGuardProtocolConfig>, QSharedPointer<ShadowsocksProtocolConfig>,
QSharedPointer<CloakProtocolConfig>, QSharedPointer<XrayProtocolConfig>, QSharedPointer<AwgProtocolConfig> >;
QSharedPointer<CloakProtocolConfig>, QSharedPointer<XrayProtocolConfig>, QSharedPointer<AwgProtocolConfig>,
QSharedPointer<SftpProtocolConfig>, QSharedPointer<Socks5ProtocolConfig>, QSharedPointer<Ikev2ProtocolConfig> >;
class ProtocolConfig
{

View File

@@ -0,0 +1,48 @@
#include "sftpProtocolConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
SftpProtocolConfig::SftpProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName) : ProtocolConfig(protocolName)
{
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString(QString::number(ProtocolProps::defaultPort(Proto::Sftp)));
serverProtocolConfig.userName = protocolConfigObject.value(config_key::userName).toString(protocols::sftp::defaultUserName);
serverProtocolConfig.password = protocolConfigObject.value(config_key::password).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
}
}
QJsonObject SftpProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.userName.isEmpty()) {
json[config_key::userName] = serverProtocolConfig.userName;
}
if (!serverProtocolConfig.password.isEmpty()) {
json[config_key::password] = serverProtocolConfig.password;
}
return json;
}
bool SftpProtocolConfig::hasEqualServerSettings(const SftpProtocolConfig &other) const
{
return serverProtocolConfig.port == other.serverProtocolConfig.port &&
serverProtocolConfig.userName == other.serverProtocolConfig.userName &&
serverProtocolConfig.password == other.serverProtocolConfig.password;
}
void SftpProtocolConfig::clearClientSettings()
{
clientProtocolConfig.isEmpty = true;
}

View File

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

View File

@@ -8,8 +8,8 @@ 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();
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString(protocols::shadowsocks::defaultPort);
serverProtocolConfig.cipher = protocolConfigObject.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher);
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {

View File

@@ -17,6 +17,15 @@ namespace shadowsocks
struct ClientProtocolConfig
{
bool isEmpty = true;
QString server;
QString serverPort;
QString localPort;
QString password;
int timeout = 60;
QString method;
QString nativeConfig;
};
}

View File

@@ -0,0 +1,48 @@
#include "socks5ProtocolConfig.h"
#include <QJsonArray>
#include <QJsonDocument>
#include "protocols/protocols_defs.h"
using namespace amnezia;
Socks5ProtocolConfig::Socks5ProtocolConfig(const QJsonObject &protocolConfigObject, const QString &protocolName) : ProtocolConfig(protocolName)
{
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString(protocols::socks5Proxy::defaultPort);
serverProtocolConfig.userName = protocolConfigObject.value(config_key::userName).toString(protocols::socks5Proxy::defaultUserName);
serverProtocolConfig.password = protocolConfigObject.value(config_key::password).toString();
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
clientProtocolConfig.isEmpty = false;
}
}
QJsonObject Socks5ProtocolConfig::toJson() const
{
QJsonObject json;
if (!serverProtocolConfig.port.isEmpty()) {
json[config_key::port] = serverProtocolConfig.port;
}
if (!serverProtocolConfig.userName.isEmpty()) {
json[config_key::userName] = serverProtocolConfig.userName;
}
if (!serverProtocolConfig.password.isEmpty()) {
json[config_key::password] = serverProtocolConfig.password;
}
return json;
}
bool Socks5ProtocolConfig::hasEqualServerSettings(const Socks5ProtocolConfig &other) const
{
return serverProtocolConfig.port == other.serverProtocolConfig.port &&
serverProtocolConfig.userName == other.serverProtocolConfig.userName &&
serverProtocolConfig.password == other.serverProtocolConfig.password;
}
void Socks5ProtocolConfig::clearClientSettings()
{
clientProtocolConfig.isEmpty = true;
}

View File

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

View File

@@ -10,9 +10,10 @@ 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();
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString(protocols::wireguard::defaultPort);
serverProtocolConfig.transportProto = protocolConfigObject.value(config_key::transport_proto).toString("udp");
serverProtocolConfig.subnetAddress = protocolConfigObject.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
serverProtocolConfig.mtu = protocolConfigObject.value(config_key::mtu).toString(protocols::wireguard::defaultMtu);
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {
@@ -59,6 +60,9 @@ QJsonObject WireGuardProtocolConfig::toJson() const
if (!serverProtocolConfig.subnetAddress.isEmpty()) {
json[config_key::subnet_address] = serverProtocolConfig.subnetAddress;
}
if (!serverProtocolConfig.mtu.isEmpty()) {
json[config_key::mtu] = serverProtocolConfig.mtu;
}
if (!clientProtocolConfig.isEmpty) {
QJsonObject clientConfigJson;

View File

@@ -27,6 +27,7 @@ namespace wireguard
QString transportProto;
QString subnetAddress;
QString mtu;
};
struct ClientProtocolConfig

View File

@@ -8,9 +8,9 @@ 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();
serverProtocolConfig.site = protocolConfigObject.value(config_key::site).toString(protocols::xray::defaultSite);
serverProtocolConfig.port = protocolConfigObject.value(config_key::port).toString(protocols::xray::defaultPort);
serverProtocolConfig.transportProto = protocolConfigObject.value(config_key::transport_proto).toString("tcp");
auto clientProtocolString = protocolConfigObject.value(config_key::last_config).toString();
if (!clientProtocolString.isEmpty()) {

View File

@@ -18,6 +18,9 @@ namespace xray
struct ClientProtocolConfig
{
bool isEmpty = true;
QString clientId;
QString nativeConfig;
};
}