mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-22 02:01:08 +07:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5600bf9768 | |||
| f3b3f165a8 |
@@ -138,7 +138,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
|||||||
|
|
||||||
if (overwriteMode == libssh::ScpOverwriteMode::ScpOverwriteExisting) {
|
if (overwriteMode == libssh::ScpOverwriteMode::ScpOverwriteExisting) {
|
||||||
e = runScript(credentials,
|
e = runScript(credentials,
|
||||||
replaceVars(QStringLiteral("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName, path),
|
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(path),
|
||||||
genVarsForScript(credentials, container)),
|
genVarsForScript(credentials, container)),
|
||||||
cbReadStd, cbReadStd);
|
cbReadStd, cbReadStd);
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
|||||||
return e;
|
return e;
|
||||||
} else if (overwriteMode == libssh::ScpOverwriteMode::ScpAppendToExisting) {
|
} else if (overwriteMode == libssh::ScpOverwriteMode::ScpAppendToExisting) {
|
||||||
e = runScript(credentials,
|
e = runScript(credentials,
|
||||||
replaceVars(QStringLiteral("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName, tmpFileName),
|
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(tmpFileName),
|
||||||
genVarsForScript(credentials, container)),
|
genVarsForScript(credentials, container)),
|
||||||
cbReadStd, cbReadStd);
|
cbReadStd, cbReadStd);
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
|||||||
return e;
|
return e;
|
||||||
|
|
||||||
e = runScript(credentials,
|
e = runScript(credentials,
|
||||||
replaceVars(QStringLiteral("sudo docker exec -i $CONTAINER_NAME sh -c \"cat %1 >> %2\"").arg(tmpFileName, path),
|
replaceVars(QString("sudo docker exec -i $CONTAINER_NAME sh -c \"cat %1 >> %2\"").arg(tmpFileName).arg(path),
|
||||||
genVarsForScript(credentials, container)),
|
genVarsForScript(credentials, container)),
|
||||||
cbReadStd, cbReadStd);
|
cbReadStd, cbReadStd);
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ QByteArray ServerController::getTextFileFromContainer(DockerContainer container,
|
|||||||
|
|
||||||
errorCode = ErrorCode::NoError;
|
errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
QString script = QStringLiteral("sudo docker exec -i %1 sh -c \"xxd -p '%2'\"").arg(ContainerProps::containerToString(container), path);
|
QString script = QString("sudo docker exec -i %1 sh -c \"xxd -p \'%2\'\"").arg(ContainerProps::containerToString(container)).arg(path);
|
||||||
|
|
||||||
QString stdOut;
|
QString stdOut;
|
||||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
||||||
@@ -383,13 +383,6 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container == DockerContainer::Xray) {
|
|
||||||
if (oldProtoConfig.value(config_key::port).toString(protocols::xray::defaultPort)
|
|
||||||
!= newProtoConfig.value(config_key::port).toString(protocols::xray::defaultPort)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ void ExportController::generateOpenVpnConfig(const QString &clientName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
||||||
for (const QString &line : std::as_const(lines)) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
||||||
for (const QString &line : std::as_const(lines)) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ void ExportController::generateAwgConfig(const QString &clientName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
||||||
for (const QString &line : std::as_const(lines)) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ void ExportController::generateShadowSocksConfig()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
||||||
for (const QString &line : std::as_const(lines)) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ void ExportController::generateCloakConfig()
|
|||||||
nativeConfig.insert("ProxyMethod", "shadowsocks");
|
nativeConfig.insert("ProxyMethod", "shadowsocks");
|
||||||
|
|
||||||
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
||||||
for (const QString &line : std::as_const(lines)) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ void ExportController::generateXrayConfig(const QString &clientName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
||||||
for (const QString &line : std::as_const(lines)) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -363,7 +363,8 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
|||||||
|
|
||||||
QJsonObject config;
|
QJsonObject config;
|
||||||
Proto mainProto = ContainerProps::defaultProtocol(container);
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
for (auto protocol : ContainerProps::protocolsForContainer(container)) {
|
const auto &protocols = ContainerProps::protocolsForContainer(container);
|
||||||
|
for (const auto &protocol : protocols) {
|
||||||
QJsonObject containerConfig;
|
QJsonObject containerConfig;
|
||||||
if (protocol == mainProto) {
|
if (protocol == mainProto) {
|
||||||
containerConfig.insert(config_key::port, port);
|
containerConfig.insert(config_key::port, port);
|
||||||
@@ -387,6 +388,7 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
containerConfig[config_key::subnet_address] = serverConfigMap.value("Address").remove("/24");
|
||||||
containerConfig[config_key::junkPacketCount] = serverConfigMap.value(config_key::junkPacketCount);
|
containerConfig[config_key::junkPacketCount] = serverConfigMap.value(config_key::junkPacketCount);
|
||||||
containerConfig[config_key::junkPacketMinSize] = serverConfigMap.value(config_key::junkPacketMinSize);
|
containerConfig[config_key::junkPacketMinSize] = serverConfigMap.value(config_key::junkPacketMinSize);
|
||||||
containerConfig[config_key::junkPacketMaxSize] = serverConfigMap.value(config_key::junkPacketMaxSize);
|
containerConfig[config_key::junkPacketMaxSize] = serverConfigMap.value(config_key::junkPacketMaxSize);
|
||||||
@@ -398,6 +400,25 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
|||||||
serverConfigMap.value(config_key::underloadPacketMagicHeader);
|
serverConfigMap.value(config_key::underloadPacketMagicHeader);
|
||||||
containerConfig[config_key::transportPacketMagicHeader] =
|
containerConfig[config_key::transportPacketMagicHeader] =
|
||||||
serverConfigMap.value(config_key::transportPacketMagicHeader);
|
serverConfigMap.value(config_key::transportPacketMagicHeader);
|
||||||
|
|
||||||
|
} else if (protocol == Proto::WireGuard) {
|
||||||
|
QString serverConfig = serverController->getTextFileFromContainer(container, credentials,
|
||||||
|
protocols::wireguard::serverConfigPath, errorCode);
|
||||||
|
|
||||||
|
QMap<QString, QString> serverConfigMap;
|
||||||
|
auto serverConfigLines = serverConfig.split("\n");
|
||||||
|
for (auto &line : serverConfigLines) {
|
||||||
|
auto trimmedLine = line.trimmed();
|
||||||
|
if (trimmedLine.startsWith("[") && trimmedLine.endsWith("]")) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
QStringList parts = trimmedLine.split(" = ");
|
||||||
|
if (parts.count() == 2) {
|
||||||
|
serverConfigMap.insert(parts[0].trimmed(), parts[1].trimmed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
containerConfig[config_key::subnet_address] = serverConfigMap.value("Address").remove("/24");
|
||||||
} else if (protocol == Proto::Sftp) {
|
} else if (protocol == Proto::Sftp) {
|
||||||
stdOut.clear();
|
stdOut.clear();
|
||||||
script = QString("sudo docker inspect --format '{{.Config.Cmd}}' %1").arg(name);
|
script = QString("sudo docker inspect --format '{{.Config.Cmd}}' %1").arg(name);
|
||||||
@@ -432,6 +453,51 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
|||||||
containerConfig.insert(config_key::userName, userName);
|
containerConfig.insert(config_key::userName, userName);
|
||||||
containerConfig.insert(config_key::password, password);
|
containerConfig.insert(config_key::password, password);
|
||||||
}
|
}
|
||||||
|
} else if (protocol == Proto::Xray) {
|
||||||
|
QString currentConfig = serverController->getTextFileFromContainer(
|
||||||
|
container, credentials, amnezia::protocols::xray::serverConfigPath, errorCode);
|
||||||
|
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(currentConfig.toUtf8());
|
||||||
|
qDebug() << doc;
|
||||||
|
if (doc.isNull() || !doc.isObject()) {
|
||||||
|
logger.error() << "Failed to parse server config JSON";
|
||||||
|
errorCode = ErrorCode::InternalError;
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
QJsonObject serverConfig = doc.object();
|
||||||
|
|
||||||
|
if (!serverConfig.contains("inbounds")) {
|
||||||
|
logger.error() << "Server config missing 'inbounds' field";
|
||||||
|
errorCode = ErrorCode::InternalError;
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonArray inbounds = serverConfig["inbounds"].toArray();
|
||||||
|
if (inbounds.isEmpty()) {
|
||||||
|
logger.error() << "Server config has empty 'inbounds' array";
|
||||||
|
errorCode = ErrorCode::InternalError;
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject inbound = inbounds[0].toObject();
|
||||||
|
if (!inbound.contains("streamSettings")) {
|
||||||
|
logger.error() << "Inbound missing 'streamSettings' field";
|
||||||
|
errorCode = ErrorCode::InternalError;
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject streamSettings = inbound["streamSettings"].toObject();
|
||||||
|
QJsonObject realitySettings = streamSettings["realitySettings"].toObject();
|
||||||
|
if (!realitySettings.contains("serverNames")) {
|
||||||
|
logger.error() << "Settings missing 'clients' field";
|
||||||
|
errorCode = ErrorCode::InternalError;
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString siteName = realitySettings["serverNames"][0].toString();
|
||||||
|
qDebug() << siteName;
|
||||||
|
|
||||||
|
containerConfig.insert(config_key::site, siteName);
|
||||||
}
|
}
|
||||||
|
|
||||||
config.insert(config_key::container, ContainerProps::containerToString(container));
|
config.insert(config_key::container, ContainerProps::containerToString(container));
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ bool XrayConfigModel::setData(const QModelIndex &index, const QVariant &value, i
|
|||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Roles::SiteRole: m_protocolConfig.insert(config_key::site, value.toString()); break;
|
case Roles::SiteRole: m_protocolConfig.insert(config_key::site, value.toString()); break;
|
||||||
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit dataChanged(index, index, QList { role });
|
emit dataChanged(index, index, QList { role });
|
||||||
@@ -35,7 +34,6 @@ QVariant XrayConfigModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Roles::SiteRole: return m_protocolConfig.value(config_key::site).toString(protocols::xray::defaultSite);
|
case Roles::SiteRole: return m_protocolConfig.value(config_key::site).toString(protocols::xray::defaultSite);
|
||||||
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::xray::defaultPort);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@@ -69,7 +67,6 @@ QHash<int, QByteArray> XrayConfigModel::roleNames() const
|
|||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
|
|
||||||
roles[SiteRole] = "site";
|
roles[SiteRole] = "site";
|
||||||
roles[PortRole] = "port";
|
|
||||||
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ class XrayConfigModel : public QAbstractListModel
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum Roles {
|
enum Roles {
|
||||||
SiteRole,
|
SiteRole
|
||||||
PortRole
|
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit XrayConfigModel(QObject *parent = nullptr);
|
explicit XrayConfigModel(QObject *parent = nullptr);
|
||||||
|
|||||||
@@ -93,9 +93,9 @@ PageType {
|
|||||||
var tmpText = textField.text
|
var tmpText = textField.text
|
||||||
tmpText = tmpText.toLocaleLowerCase()
|
tmpText = tmpText.toLocaleLowerCase()
|
||||||
|
|
||||||
var indexHttps = tmpText.indexOf("https://")
|
if (tmpText.startsWith("https://")) {
|
||||||
if (indexHttps === 0) {
|
|
||||||
tmpText = textField.text.substring(8)
|
tmpText = textField.text.substring(8)
|
||||||
|
site = tmpText
|
||||||
} else {
|
} else {
|
||||||
site = textField.text
|
site = textField.text
|
||||||
}
|
}
|
||||||
@@ -103,29 +103,8 @@ PageType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
|
||||||
id: portTextField
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 16
|
|
||||||
|
|
||||||
enabled: delegateItem.isEnabled
|
|
||||||
|
|
||||||
headerText: qsTr("Port")
|
|
||||||
textField.text: port
|
|
||||||
textField.maximumLength: 5
|
|
||||||
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
|
||||||
if (textField.text !== port) {
|
|
||||||
port = textField.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkEmptyText: true
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
id: saveButton
|
id: basicButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|||||||
Reference in New Issue
Block a user