Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD

This commit is contained in:
vladimir.kuznetsov 2024-05-20 10:49:42 +02:00
commit 3241782098
308 changed files with 23129 additions and 5889 deletions

View file

@ -4,17 +4,26 @@
#include <QDir>
#include <QEventLoop>
#include <QJsonObject>
#include <QStandardPaths>
#include <QRandomGenerator>
#include <QStandardPaths>
#include "core/errorstrings.h"
#include "core/controllers/serverController.h"
#include "utilities.h"
#include "core/controllers/vpnConfigurationController.h"
#include "core/errorstrings.h"
#include "core/networkUtilities.h"
#include "logger.h"
#include "ui/models/protocols/awgConfigModel.h"
#include "ui/models/protocols/wireguardConfigModel.h"
#include "utilities.h"
#ifdef Q_OS_IOS
#include <AmneziaVPN-Swift.h>
#endif
namespace
{
Logger logger("ServerController");
#ifdef Q_OS_WINDOWS
QString getNextDriverLetter()
{
@ -41,14 +50,15 @@ namespace
#endif
}
InstallController::InstallController(const QSharedPointer<ServersModel> &serversModel,
const QSharedPointer<ContainersModel> &containersModel,
InstallController::InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
const QSharedPointer<ProtocolsModel> &protocolsModel,
const QSharedPointer<ClientManagementModel> &clientManagementModel,
const std::shared_ptr<Settings> &settings, QObject *parent)
: QObject(parent),
m_serversModel(serversModel),
m_containersModel(containersModel),
m_protocolModel(protocolsModel),
m_clientManagementModel(clientManagementModel),
m_settings(settings)
{
}
@ -73,21 +83,26 @@ void InstallController::install(DockerContainer container, int port, TransportPr
if (protocol == mainProto) {
containerConfig.insert(config_key::port, QString::number(port));
containerConfig.insert(config_key::transport_proto,
ProtocolProps::transportProtoToString(transportProto, protocol));
containerConfig.insert(config_key::transport_proto, ProtocolProps::transportProtoToString(transportProto, protocol));
if (container == DockerContainer::Awg) {
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(3, 10));
QString junkPacketMinSize = QString::number(50);
QString junkPacketMaxSize = QString::number(1000);
QString initPacketJunkSize = QString::number(QRandomGenerator::global()->bounded(15, 150));
QString responsePacketJunkSize = QString::number(QRandomGenerator::global()->bounded(15, 150));
int s1 = QRandomGenerator::global()->bounded(15, 150);
int s2 = QRandomGenerator::global()->bounded(15, 150);
while (s1 + AwgConstant::messageInitiationSize == s2 + AwgConstant::messageResponseSize) {
s2 = QRandomGenerator::global()->bounded(15, 150);
}
QString initPacketJunkSize = QString::number(s1);
QString responsePacketJunkSize = QString::number(s2);
QSet<QString> headersValue;
while (headersValue.size() != 4) {
auto max = (std::numeric_limits<qint32>::max)();
headersValue.insert(QString::number(QRandomGenerator::global()->bounded(1, max)));
headersValue.insert(QString::number(QRandomGenerator::global()->bounded(5, max)));
}
auto headersValueList = headersValue.values();
@ -106,9 +121,7 @@ void InstallController::install(DockerContainer container, int port, TransportPr
containerConfig[config_key::responsePacketMagicHeader] = responsePacketMagicHeader;
containerConfig[config_key::underloadPacketMagicHeader] = underloadPacketMagicHeader;
containerConfig[config_key::transportPacketMagicHeader] = transportPacketMagicHeader;
}
if (container == DockerContainer::Sftp) {
} else if (container == DockerContainer::Sftp) {
containerConfig.insert(config_key::userName, protocols::sftp::defaultUserName);
containerConfig.insert(config_key::password, Utils::getRandomString(10));
}
@ -118,109 +131,145 @@ void InstallController::install(DockerContainer container, int port, TransportPr
config.insert(ProtocolProps::protoToString(protocol), containerConfig);
}
ServerCredentials serverCredentials;
if (m_shouldCreateServer) {
if (isServerAlreadyExists()) {
return;
}
installServer(container, config);
serverCredentials = m_processedServerCredentials;
} else {
installContainer(container, config);
int serverIndex = m_serversModel->getProcessedServerIndex();
serverCredentials = qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
}
}
void InstallController::installServer(DockerContainer container, QJsonObject &config)
{
ServerController serverController(m_settings);
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
connect(serverController.get(), &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
connect(this, &InstallController::cancelInstallation, serverController.get(), &ServerController::cancelInstallation);
QMap<DockerContainer, QJsonObject> installedContainers;
ErrorCode errorCode =
serverController.getAlreadyInstalledContainers(m_currentlyInstalledServerCredentials, installedContainers);
ErrorCode errorCode = getAlreadyInstalledContainers(serverCredentials, serverController, installedContainers);
if (errorCode) {
emit installationErrorOccurred(errorString(errorCode));
return;
}
QString finishMessage = "";
if (!installedContainers.contains(container)) {
errorCode = serverController.setupContainer(m_currentlyInstalledServerCredentials, container, config);
errorCode = serverController->setupContainer(serverCredentials, container, config);
if (errorCode) {
emit installationErrorOccurred(errorString(errorCode));
return;
}
installedContainers.insert(container, config);
finishMessage = tr("%1 installed successfully. ").arg(ContainerProps::containerHumanNames().value(container));
} else {
finishMessage = tr("%1 is already installed on the server. ").arg(ContainerProps::containerHumanNames().value(container));
}
if (errorCode) {
emit installationErrorOccurred(errorString(errorCode));
return;
}
if (m_shouldCreateServer) {
installServer(container, installedContainers, serverCredentials, serverController, finishMessage);
} else {
installContainer(container, installedContainers, serverCredentials, serverController, finishMessage);
}
}
void InstallController::installServer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
const ServerCredentials &serverCredentials, const QSharedPointer<ServerController> &serverController,
QString &finishMessage)
{
if (installedContainers.size() > 1) {
finishMessage += tr("\nAdded containers that were already installed on the server");
}
if (errorCode == ErrorCode::NoError) {
QJsonObject server;
server.insert(config_key::hostName, m_currentlyInstalledServerCredentials.hostName);
server.insert(config_key::userName, m_currentlyInstalledServerCredentials.userName);
server.insert(config_key::password, m_currentlyInstalledServerCredentials.secretData);
server.insert(config_key::port, m_currentlyInstalledServerCredentials.port);
server.insert(config_key::description, m_settings->nextAvailableServerName());
QJsonObject server;
server.insert(config_key::hostName, m_processedServerCredentials.hostName);
server.insert(config_key::userName, m_processedServerCredentials.userName);
server.insert(config_key::password, m_processedServerCredentials.secretData);
server.insert(config_key::port, m_processedServerCredentials.port);
server.insert(config_key::description, m_settings->nextAvailableServerName());
QJsonArray containerConfigs;
for (const QJsonObject &containerConfig : qAsConst(installedContainers)) {
QJsonArray containerConfigs;
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
auto containerConfig = iterator.value();
if (ContainerProps::isSupportedByCurrentPlatform(container)) {
auto errorCode = vpnConfigurationController.createProtocolConfigForContainer(m_processedServerCredentials, iterator.key(),
containerConfig);
if (errorCode) {
emit installationErrorOccurred(errorString(errorCode));
return;
}
containerConfigs.append(containerConfig);
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
if (errorCode) {
emit installationErrorOccurred(errorString(errorCode));
return;
}
} else {
containerConfigs.append(containerConfig);
}
server.insert(config_key::containers, containerConfigs);
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
m_serversModel->addServer(server);
emit installServerFinished(finishMessage);
return;
}
emit installationErrorOccurred(errorString(errorCode));
server.insert(config_key::containers, containerConfigs);
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
m_serversModel->addServer(server);
emit installServerFinished(finishMessage);
}
void InstallController::installContainer(DockerContainer container, QJsonObject &config)
void InstallController::installContainer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
const ServerCredentials &serverCredentials,
const QSharedPointer<ServerController> &serverController, QString &finishMessage)
{
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
ServerController serverController(m_settings);
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
QMap<DockerContainer, QJsonObject> installedContainers;
ErrorCode errorCode = serverController.getAlreadyInstalledContainers(serverCredentials, installedContainers);
QString finishMessage = "";
if (!installedContainers.contains(container)) {
errorCode = serverController.setupContainer(serverCredentials, container, config);
installedContainers.insert(container, config);
finishMessage = tr("%1 installed successfully. ").arg(ContainerProps::containerHumanNames().value(container));
} else {
finishMessage = tr("%1 is already installed on the server. ").arg(ContainerProps::containerHumanNames().value(container));
}
bool isInstalledContainerAddedToGui = false;
if (errorCode == ErrorCode::NoError) {
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key());
if (containerConfig.isEmpty()) {
m_serversModel->addContainerConfig(iterator.key(), iterator.value());
if (container != iterator.key()) { // skip the newly installed container
isInstalledContainerAddedToGui = true;
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key());
if (containerConfig.isEmpty()) {
containerConfig = iterator.value();
if (ContainerProps::isSupportedByCurrentPlatform(container)) {
auto errorCode =
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, iterator.key(), containerConfig);
if (errorCode) {
emit installationErrorOccurred(errorString(errorCode));
return;
}
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
if (errorCode) {
emit installationErrorOccurred(errorString(errorCode));
return;
}
} else {
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
}
if (container != iterator.key()) { // skip the newly installed container
isInstalledContainerAddedToGui = true;
}
}
if (isInstalledContainerAddedToGui) {
finishMessage += tr("\nAlready installed containers were found on the server. "
"All installed containers have been added to the application");
}
emit installContainerFinished(finishMessage, ContainerProps::containerService(container) == ServiceType::Other);
return;
}
if (isInstalledContainerAddedToGui) {
finishMessage += tr("\nAlready installed containers were found on the server. "
"All installed containers have been added to the application");
}
emit installationErrorOccurred(errorString(errorCode));
emit installContainerFinished(finishMessage, ContainerProps::containerService(container) == ServiceType::Other);
}
bool InstallController::isServerAlreadyExists()
@ -229,8 +278,7 @@ bool InstallController::isServerAlreadyExists()
auto modelIndex = m_serversModel->index(i);
const ServerCredentials credentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(modelIndex, ServersModel::Roles::CredentialsRole));
if (m_currentlyInstalledServerCredentials.hostName == credentials.hostName
&& m_currentlyInstalledServerCredentials.port == credentials.port) {
if (m_processedServerCredentials.hostName == credentials.hostName && m_processedServerCredentials.port == credentials.port) {
emit serverAlreadyExists(i);
return true;
}
@ -244,18 +292,40 @@ void InstallController::scanServerForInstalledContainers()
ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
ServerController serverController(m_settings);
QMap<DockerContainer, QJsonObject> installedContainers;
ErrorCode errorCode = serverController.getAlreadyInstalledContainers(serverCredentials, installedContainers);
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
ErrorCode errorCode = getAlreadyInstalledContainers(serverCredentials, serverController, installedContainers);
if (errorCode == ErrorCode::NoError) {
bool isInstalledContainerAddedToGui = false;
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key());
auto container = iterator.key();
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
if (containerConfig.isEmpty()) {
m_serversModel->addContainerConfig(iterator.key(), iterator.value());
containerConfig = iterator.value();
if (ContainerProps::isSupportedByCurrentPlatform(container)) {
auto errorCode =
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, container, containerConfig);
if (errorCode) {
emit installationErrorOccurred(errorString(errorCode));
return;
}
m_serversModel->addContainerConfig(container, containerConfig);
errorCode = m_clientManagementModel->appendClient(container, serverCredentials, containerConfig,
QString("Admin [%1]").arg(QSysInfo::prettyProductName()),
serverController);
if (errorCode) {
emit installationErrorOccurred(errorString(errorCode));
return;
}
} else {
m_serversModel->addContainerConfig(container, containerConfig);
}
isInstalledContainerAddedToGui = true;
}
}
@ -267,6 +337,160 @@ void InstallController::scanServerForInstalledContainers()
emit installationErrorOccurred(errorString(errorCode));
}
ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentials &credentials,
const QSharedPointer<ServerController> &serverController,
QMap<DockerContainer, QJsonObject> &installedContainers)
{
QString stdOut;
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
stdOut += data + "\n";
return ErrorCode::NoError;
};
auto cbReadStdErr = [&](const QString &data, libssh::Client &) {
stdOut += data + "\n";
return ErrorCode::NoError;
};
QString script = QString("sudo docker ps --format '{{.Names}} {{.Ports}}'");
ErrorCode errorCode = serverController->runScript(credentials, script, cbReadStdOut, cbReadStdErr);
if (errorCode != ErrorCode::NoError) {
return errorCode;
}
auto containersInfo = stdOut.split("\n");
for (auto &containerInfo : containersInfo) {
if (containerInfo.isEmpty()) {
continue;
}
const static QRegularExpression containerAndPortRegExp("(amnezia[-a-z]*).*?:([0-9]*)->[0-9]*/(udp|tcp).*");
QRegularExpressionMatch containerAndPortMatch = containerAndPortRegExp.match(containerInfo);
if (containerAndPortMatch.hasMatch()) {
QString name = containerAndPortMatch.captured(1);
QString port = containerAndPortMatch.captured(2);
QString transportProto = containerAndPortMatch.captured(3);
DockerContainer container = ContainerProps::containerFromString(name);
QJsonObject config;
Proto mainProto = ContainerProps::defaultProtocol(container);
for (auto protocol : ContainerProps::protocolsForContainer(container)) {
QJsonObject containerConfig;
if (protocol == mainProto) {
containerConfig.insert(config_key::port, port);
containerConfig.insert(config_key::transport_proto, transportProto);
if (protocol == Proto::Awg) {
QString serverConfigPath;
if (container == DockerContainer::Awg) {
if (serverController->isNewAwgContainer(credentials)) {
serverConfigPath = amnezia::protocols::awg::serverConfigPath;
} else {
serverConfigPath = "/opt/amnezia/awg/wg0.conf";
}
}
QString serverConfig = serverController->getTextFileFromContainer(container, credentials,
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::junkPacketCount] = serverConfigMap.value(config_key::junkPacketCount);
containerConfig[config_key::junkPacketMinSize] = serverConfigMap.value(config_key::junkPacketMinSize);
containerConfig[config_key::junkPacketMaxSize] = serverConfigMap.value(config_key::junkPacketMaxSize);
containerConfig[config_key::initPacketJunkSize] = serverConfigMap.value(config_key::initPacketJunkSize);
containerConfig[config_key::responsePacketJunkSize] = serverConfigMap.value(config_key::responsePacketJunkSize);
containerConfig[config_key::initPacketMagicHeader] = serverConfigMap.value(config_key::initPacketMagicHeader);
containerConfig[config_key::responsePacketMagicHeader] = serverConfigMap.value(config_key::responsePacketMagicHeader);
containerConfig[config_key::underloadPacketMagicHeader] =
serverConfigMap.value(config_key::underloadPacketMagicHeader);
containerConfig[config_key::transportPacketMagicHeader] =
serverConfigMap.value(config_key::transportPacketMagicHeader);
} else if (protocol == Proto::Sftp) {
stdOut.clear();
script = QString("sudo docker inspect --format '{{.Config.Cmd}}' %1").arg(name);
ErrorCode errorCode = serverController->runScript(credentials, script, cbReadStdOut, cbReadStdErr);
if (errorCode != ErrorCode::NoError) {
return errorCode;
}
auto sftpInfo = stdOut.split(":");
if (sftpInfo.size() < 2) {
logger.error() << "Key parameters for the sftp container are missing";
continue;
}
auto userName = sftpInfo.at(0);
userName = userName.remove(0, 1);
auto password = sftpInfo.at(1);
containerConfig.insert(config_key::userName, userName);
containerConfig.insert(config_key::password, password);
}
config.insert(config_key::container, ContainerProps::containerToString(container));
}
config.insert(ProtocolProps::protoToString(protocol), containerConfig);
}
installedContainers.insert(container, config);
}
const static QRegularExpression torOrDnsRegExp("(amnezia-(?:torwebsite|dns)).*?([0-9]*)/(udp|tcp).*");
QRegularExpressionMatch torOrDnsRegMatch = torOrDnsRegExp.match(containerInfo);
if (torOrDnsRegMatch.hasMatch()) {
QString name = torOrDnsRegMatch.captured(1);
QString port = torOrDnsRegMatch.captured(2);
QString transportProto = torOrDnsRegMatch.captured(3);
DockerContainer container = ContainerProps::containerFromString(name);
QJsonObject config;
Proto mainProto = ContainerProps::defaultProtocol(container);
for (auto protocol : ContainerProps::protocolsForContainer(container)) {
QJsonObject containerConfig;
if (protocol == mainProto) {
containerConfig.insert(config_key::port, port);
containerConfig.insert(config_key::transport_proto, transportProto);
if (protocol == Proto::TorWebSite) {
stdOut.clear();
script = QString("sudo docker exec -i %1 sh -c 'cat /var/lib/tor/hidden_service/hostname'").arg(name);
ErrorCode errorCode = serverController->runScript(credentials, script, cbReadStdOut, cbReadStdErr);
if (errorCode != ErrorCode::NoError) {
return errorCode;
}
if (stdOut.isEmpty()) {
logger.error() << "Key parameters for the tor container are missing";
continue;
}
QString onion = stdOut;
onion.replace("\n", "");
containerConfig.insert(config_key::site, onion);
}
config.insert(config_key::container, ContainerProps::containerToString(container));
}
config.insert(ProtocolProps::protoToString(protocol), containerConfig);
}
installedContainers.insert(container, config);
}
}
return ErrorCode::NoError;
}
void InstallController::updateContainer(QJsonObject config)
{
int serverIndex = m_serversModel->getProcessedServerIndex();
@ -278,11 +502,12 @@ void InstallController::updateContainer(QJsonObject config)
ErrorCode errorCode = ErrorCode::NoError;
if (isUpdateDockerContainerRequired(container, oldContainerConfig, config)) {
ServerController serverController(m_settings);
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
connect(serverController.get(), &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
connect(this, &InstallController::cancelInstallation, serverController.get(), &ServerController::cancelInstallation);
errorCode = serverController.updateContainer(serverCredentials, container, oldContainerConfig, config);
errorCode = serverController->updateContainer(serverCredentials, container, oldContainerConfig, config);
clearCachedProfile(serverController);
}
if (errorCode == ErrorCode::NoError) {
@ -307,8 +532,13 @@ void InstallController::rebootProcessedServer()
int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
m_serversModel->rebootServer();
emit rebootProcessedServerFinished(tr("Server '%1' was rebooted").arg(serverName));
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
const auto errorCode = m_serversModel->rebootServer(serverController);
if (errorCode == ErrorCode::NoError) {
emit rebootProcessedServerFinished(tr("Server '%1' was rebooted").arg(serverName));
} else {
emit installationErrorOccurred(errorString(errorCode));
}
}
void InstallController::removeProcessedServer()
@ -325,7 +555,8 @@ void InstallController::removeAllContainers()
int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
ErrorCode errorCode = m_serversModel->removeAllContainers();
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
ErrorCode errorCode = m_serversModel->removeAllContainers(serverController);
if (errorCode == ErrorCode::NoError) {
emit removeAllContainersFinished(tr("All containers from server '%1' have been removed").arg(serverName));
return;
@ -333,44 +564,84 @@ void InstallController::removeAllContainers()
emit installationErrorOccurred(errorString(errorCode));
}
void InstallController::removeCurrentlyProcessedContainer()
void InstallController::removeProcessedContainer()
{
int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
int container = m_containersModel->getCurrentlyProcessedContainerIndex();
QString containerName = m_containersModel->getCurrentlyProcessedContainerName();
int container = m_containersModel->getProcessedContainerIndex();
QString containerName = m_containersModel->getProcessedContainerName();
ErrorCode errorCode = m_serversModel->removeContainer(container);
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
ErrorCode errorCode = m_serversModel->removeContainer(serverController, container);
if (errorCode == ErrorCode::NoError) {
emit removeCurrentlyProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName, serverName));
emit removeProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName, serverName));
return;
}
emit installationErrorOccurred(errorString(errorCode));
}
void InstallController::removeApiConfig(const int serverIndex)
{
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
#ifdef Q_OS_IOS
QString vpncName = QString("%1 (%2) %3")
.arg(serverConfig[config_key::description].toString())
.arg(serverConfig[config_key::hostName].toString())
.arg(serverConfig[config_key::vpnproto].toString());
AmneziaVPN::removeVPNC(vpncName.toStdString());
#endif
serverConfig.remove(config_key::dns1);
serverConfig.remove(config_key::dns2);
serverConfig.remove(config_key::containers);
serverConfig.remove(config_key::hostName);
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
m_serversModel->editServer(serverConfig, serverIndex);
}
void InstallController::clearCachedProfile(QSharedPointer<ServerController> serverController)
{
if (serverController.isNull()) {
serverController.reset(new ServerController(m_settings));
}
int serverIndex = m_serversModel->getProcessedServerIndex();
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getProcessedContainerIndex());
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
m_serversModel->clearCachedProfile(container);
m_clientManagementModel->revokeClient(containerConfig, container, serverCredentials, serverIndex, serverController);
emit cachedProfileCleared(tr("%1 cached profile cleared").arg(ContainerProps::containerHumanNames().value(container)));
}
QRegularExpression InstallController::ipAddressPortRegExp()
{
return Utils::ipAddressPortRegExp();
return NetworkUtilities::ipAddressPortRegExp();
}
QRegularExpression InstallController::ipAddressRegExp()
{
return Utils::ipAddressRegExp();
return NetworkUtilities::ipAddressRegExp();
}
void InstallController::setCurrentlyInstalledServerCredentials(const QString &hostName, const QString &userName,
const QString &secretData)
void InstallController::setProcessedServerCredentials(const QString &hostName, const QString &userName, const QString &secretData)
{
m_currentlyInstalledServerCredentials.hostName = hostName;
if (m_currentlyInstalledServerCredentials.hostName.contains(":")) {
m_currentlyInstalledServerCredentials.port =
m_currentlyInstalledServerCredentials.hostName.split(":").at(1).toInt();
m_currentlyInstalledServerCredentials.hostName = m_currentlyInstalledServerCredentials.hostName.split(":").at(0);
m_processedServerCredentials.hostName = hostName;
if (m_processedServerCredentials.hostName.contains(":")) {
m_processedServerCredentials.port = m_processedServerCredentials.hostName.split(":").at(1).toInt();
m_processedServerCredentials.hostName = m_processedServerCredentials.hostName.split(":").at(0);
}
m_currentlyInstalledServerCredentials.userName = userName;
m_currentlyInstalledServerCredentials.secretData = secretData;
m_processedServerCredentials.userName = userName;
m_processedServerCredentials.secretData = secretData;
}
void InstallController::setShouldCreateServer(bool shouldCreateServer)
@ -397,8 +668,7 @@ void InstallController::mountSftpDrive(const QString &port, const QString &passw
cmd = "C:\\Program Files\\SSHFS-Win\\bin\\sshfs.exe";
#elif defined AMNEZIA_DESKTOP
mountPath =
QString("%1/sftp:%2:%3").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation), hostname, port);
mountPath = QString("%1/sftp:%2:%3").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation), hostname, port);
QDir dir(mountPath);
if (!dir.exists()) {
dir.mkpath(mountPath);
@ -450,19 +720,19 @@ void InstallController::mountSftpDrive(const QString &port, const QString &passw
process->write((password + "\n").toUtf8());
}
// qDebug().noquote() << "onPushButtonSftpMountDriveClicked" << args;
#endif
}
bool InstallController::checkSshConnection()
bool InstallController::checkSshConnection(QSharedPointer<ServerController> serverController)
{
ServerController serverController(m_settings);
if (serverController.isNull()) {
serverController.reset(new ServerController(m_settings));
}
ErrorCode errorCode = ErrorCode::NoError;
m_privateKeyPassphrase = "";
if (m_currentlyInstalledServerCredentials.secretData.contains("BEGIN")
&& m_currentlyInstalledServerCredentials.secretData.contains("PRIVATE KEY")) {
if (m_processedServerCredentials.secretData.contains("BEGIN") && m_processedServerCredentials.secretData.contains("PRIVATE KEY")) {
auto passphraseCallback = [this]() {
emit passphraseRequestStarted();
QEventLoop loop;
@ -473,10 +743,9 @@ bool InstallController::checkSshConnection()
};
QString decryptedPrivateKey;
errorCode = serverController.getDecryptedPrivateKey(m_currentlyInstalledServerCredentials, decryptedPrivateKey,
passphraseCallback);
errorCode = serverController->getDecryptedPrivateKey(m_processedServerCredentials, decryptedPrivateKey, passphraseCallback);
if (errorCode == ErrorCode::NoError) {
m_currentlyInstalledServerCredentials.secretData = decryptedPrivateKey;
m_processedServerCredentials.secretData = decryptedPrivateKey;
} else {
emit installationErrorOccurred(errorString(errorCode));
return false;
@ -484,7 +753,7 @@ bool InstallController::checkSshConnection()
}
QString output;
output = serverController.checkSshConnection(m_currentlyInstalledServerCredentials, &errorCode);
output = serverController->checkSshConnection(m_processedServerCredentials, errorCode);
if (errorCode != ErrorCode::NoError) {
emit installationErrorOccurred(errorString(errorCode));
@ -508,10 +777,10 @@ void InstallController::setEncryptedPassphrase(QString passphrase)
void InstallController::addEmptyServer()
{
QJsonObject server;
server.insert(config_key::hostName, m_currentlyInstalledServerCredentials.hostName);
server.insert(config_key::userName, m_currentlyInstalledServerCredentials.userName);
server.insert(config_key::password, m_currentlyInstalledServerCredentials.secretData);
server.insert(config_key::port, m_currentlyInstalledServerCredentials.port);
server.insert(config_key::hostName, m_processedServerCredentials.hostName);
server.insert(config_key::userName, m_processedServerCredentials.userName);
server.insert(config_key::password, m_processedServerCredentials.secretData);
server.insert(config_key::port, m_processedServerCredentials.port);
server.insert(config_key::description, m_settings->nextAvailableServerName());
server.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
@ -521,7 +790,8 @@ void InstallController::addEmptyServer()
emit installServerFinished(tr("Server added successfully"));
}
bool InstallController::isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig)
bool InstallController::isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig,
const QJsonObject &newConfig)
{
Proto mainProto = ContainerProps::defaultProtocol(container);
@ -532,17 +802,17 @@ bool InstallController::isUpdateDockerContainerRequired(const DockerContainer co
const AwgConfig oldConfig(oldProtoConfig);
const AwgConfig newConfig(newProtoConfig);
if (!oldConfig.hasEqualServerSettings(newConfig)) {
return true;
if (oldConfig.hasEqualServerSettings(newConfig)) {
return false;
}
} else if (container == DockerContainer::WireGuard) {
const WgConfig oldConfig(oldProtoConfig);
const WgConfig newConfig(newProtoConfig);
if (!oldConfig.hasEqualServerSettings(newConfig)) {
return true;
if (oldConfig.hasEqualServerSettings(newConfig)) {
return false;
}
}
return false;
return true;
}