mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-02 08:33:38 +02:00
fix: various fixes (#2664)
* fix: fixed nextAvailableServerName * fix: fixed password request for ssh key
This commit is contained in:
@@ -486,7 +486,7 @@ QJsonObject ImportController::extractOpenVpnConfig(const QString &data) const
|
|||||||
QJsonObject config;
|
QJsonObject config;
|
||||||
config[configKey::containers] = arr;
|
config[configKey::containers] = arr;
|
||||||
config[configKey::defaultContainer] = configKey::amneziaOpenvpn;
|
config[configKey::defaultContainer] = configKey::amneziaOpenvpn;
|
||||||
config[configKey::description] = m_appSettingsRepository->nextAvailableServerName();
|
config[configKey::description] = m_serversRepository->nextAvailableServerName();
|
||||||
|
|
||||||
const static QRegularExpression dnsRegExp("dhcp-option DNS (\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
|
const static QRegularExpression dnsRegExp("dhcp-option DNS (\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
|
||||||
QRegularExpressionMatchIterator dnsMatch = dnsRegExp.globalMatch(data);
|
QRegularExpressionMatchIterator dnsMatch = dnsRegExp.globalMatch(data);
|
||||||
@@ -645,7 +645,7 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data, Config
|
|||||||
QJsonObject config;
|
QJsonObject config;
|
||||||
config[configKey::containers] = arr;
|
config[configKey::containers] = arr;
|
||||||
config[configKey::defaultContainer] = containerName;
|
config[configKey::defaultContainer] = containerName;
|
||||||
config[configKey::description] = m_appSettingsRepository->nextAvailableServerName();
|
config[configKey::description] = m_serversRepository->nextAvailableServerName();
|
||||||
|
|
||||||
const static QRegularExpression dnsRegExp(
|
const static QRegularExpression dnsRegExp(
|
||||||
"DNS = "
|
"DNS = "
|
||||||
@@ -699,7 +699,7 @@ QJsonObject ImportController::extractXrayConfig(const QString &data, ConfigTypes
|
|||||||
? configKey::amneziaSsxray
|
? configKey::amneziaSsxray
|
||||||
: configKey::amneziaXray;
|
: configKey::amneziaXray;
|
||||||
if (description.isEmpty()) {
|
if (description.isEmpty()) {
|
||||||
config[configKey::description] = m_appSettingsRepository->nextAvailableServerName();
|
config[configKey::description] = m_serversRepository->nextAvailableServerName();
|
||||||
} else {
|
} else {
|
||||||
config[configKey::description] = description;
|
config[configKey::description] = description;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ void InstallController::addEmptyServer(const ServerCredentials &credentials)
|
|||||||
serverConfig.userName = credentials.userName;
|
serverConfig.userName = credentials.userName;
|
||||||
serverConfig.password = credentials.secretData;
|
serverConfig.password = credentials.secretData;
|
||||||
serverConfig.port = credentials.port;
|
serverConfig.port = credentials.port;
|
||||||
serverConfig.description = m_appSettingsRepository->nextAvailableServerName();
|
serverConfig.description = m_serversRepository->nextAvailableServerName();
|
||||||
serverConfig.displayName = serverConfig.description.isEmpty() ? serverConfig.hostName : serverConfig.description;
|
serverConfig.displayName = serverConfig.description.isEmpty() ? serverConfig.hostName : serverConfig.description;
|
||||||
serverConfig.defaultContainer = DockerContainer::None;
|
serverConfig.defaultContainer = DockerContainer::None;
|
||||||
|
|
||||||
@@ -1170,7 +1170,7 @@ ErrorCode InstallController::installServer(const ServerCredentials &credentials,
|
|||||||
serverConfig.userName = credentials.userName;
|
serverConfig.userName = credentials.userName;
|
||||||
serverConfig.password = credentials.secretData;
|
serverConfig.password = credentials.secretData;
|
||||||
serverConfig.port = credentials.port;
|
serverConfig.port = credentials.port;
|
||||||
serverConfig.description = m_appSettingsRepository->nextAvailableServerName();
|
serverConfig.description = m_serversRepository->nextAvailableServerName();
|
||||||
|
|
||||||
for (auto iterator = preparedContainers.begin(); iterator != preparedContainers.end(); iterator++) {
|
for (auto iterator = preparedContainers.begin(); iterator != preparedContainers.end(); iterator++) {
|
||||||
serverConfig.containers.insert(iterator.key(), iterator.value());
|
serverConfig.containers.insert(iterator.key(), iterator.value());
|
||||||
@@ -1240,28 +1240,26 @@ ErrorCode InstallController::installContainer(const QString &serverId, DockerCon
|
|||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode InstallController::checkSshConnection(const ServerCredentials &credentials, QString &output,
|
ErrorCode InstallController::checkSshConnection(ServerCredentials &credentials, QString &output,
|
||||||
std::function<QString()> passphraseCallback)
|
std::function<QString()> passphraseCallback)
|
||||||
{
|
{
|
||||||
SshSession sshSession(this);
|
SshSession sshSession(this);
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
ServerCredentials processedCredentials = credentials;
|
if (credentials.secretData.contains("BEGIN") && credentials.secretData.contains("PRIVATE KEY")) {
|
||||||
|
|
||||||
if (processedCredentials.secretData.contains("BEGIN") && processedCredentials.secretData.contains("PRIVATE KEY")) {
|
|
||||||
if (!passphraseCallback) {
|
if (!passphraseCallback) {
|
||||||
return ErrorCode::SshPrivateKeyError;
|
return ErrorCode::SshPrivateKeyError;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString decryptedPrivateKey;
|
QString decryptedPrivateKey;
|
||||||
errorCode = sshSession.getDecryptedPrivateKey(processedCredentials, decryptedPrivateKey, passphraseCallback);
|
errorCode = sshSession.getDecryptedPrivateKey(credentials, decryptedPrivateKey, passphraseCallback);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
processedCredentials.secretData = decryptedPrivateKey;
|
credentials.secretData = decryptedPrivateKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
output = sshSession.checkSshConnection(processedCredentials, errorCode);
|
output = sshSession.checkSshConnection(credentials, errorCode);
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ public:
|
|||||||
|
|
||||||
bool isUpdateDockerContainerRequired(DockerContainer container, const ContainerConfig &oldConfig, const ContainerConfig &newConfig);
|
bool isUpdateDockerContainerRequired(DockerContainer container, const ContainerConfig &oldConfig, const ContainerConfig &newConfig);
|
||||||
|
|
||||||
ErrorCode checkSshConnection(const ServerCredentials &credentials, QString &output, std::function<QString()> passphraseCallback = nullptr);
|
ErrorCode checkSshConnection(ServerCredentials &credentials, QString &output,
|
||||||
|
std::function<QString()> passphraseCallback = nullptr);
|
||||||
|
|
||||||
bool isServerAlreadyExists(const ServerCredentials &credentials, int &existingServerIndex);
|
bool isServerAlreadyExists(const ServerCredentials &credentials, int &existingServerIndex);
|
||||||
|
|
||||||
|
|||||||
@@ -363,6 +363,6 @@ void SettingsController::disablePremV1MigrationReminder()
|
|||||||
|
|
||||||
QString SettingsController::nextAvailableServerName() const
|
QString SettingsController::nextAvailableServerName() const
|
||||||
{
|
{
|
||||||
return m_appSettingsRepository->nextAvailableServerName();
|
return m_serversRepository->nextAvailableServerName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "core/controllers/gatewayController.h"
|
#include "core/controllers/gatewayController.h"
|
||||||
#include "core/utils/constants/apiKeys.h"
|
#include "core/utils/constants/apiKeys.h"
|
||||||
#include "core/utils/errorStrings.h"
|
|
||||||
#include "core/utils/selfhosted/scriptsRegistry.h"
|
#include "core/utils/selfhosted/scriptsRegistry.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -109,7 +108,7 @@ void UpdateController::fetchGatewayUrl()
|
|||||||
.then(this, [this, gatewayController](QPair<ErrorCode, QByteArray> result) {
|
.then(this, [this, gatewayController](QPair<ErrorCode, QByteArray> result) {
|
||||||
auto [err, gatewayResponse] = result;
|
auto [err, gatewayResponse] = result;
|
||||||
if (err != ErrorCode::NoError) {
|
if (err != ErrorCode::NoError) {
|
||||||
logger.error() << errorString(err);
|
logger.error() << "Gateway request failed, error code:" << static_cast<int>(err);
|
||||||
finishUpdateCheck();
|
finishUpdateCheck();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -250,17 +249,9 @@ void UpdateController::runInstaller()
|
|||||||
runLinuxInstaller(kInstallerLocalPath);
|
runLinuxInstaller(kInstallerLocalPath);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError
|
logger.error() << "Installer download failed, network error:" << static_cast<int>(reply->error())
|
||||||
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) {
|
<< reply->errorString();
|
||||||
logger.error() << errorString(ErrorCode::ApiConfigTimeoutError);
|
logger.error() << "HTTP status:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
} else {
|
|
||||||
QString err = reply->errorString();
|
|
||||||
logger.error() << QString::fromUtf8(reply->readAll());
|
|
||||||
logger.error() << "Network error code:" << QString::number(static_cast<int>(reply->error()));
|
|
||||||
logger.error() << "Error message:" << err;
|
|
||||||
logger.error() << "HTTP status:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
||||||
logger.error() << errorString(ErrorCode::ApiConfigDownloadError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -426,26 +426,6 @@ void SecureAppSettingsRepository::clearSettings()
|
|||||||
emit settingsCleared();
|
emit settingsCleared();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SecureAppSettingsRepository::nextAvailableServerName() const
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
bool nameExist = false;
|
|
||||||
|
|
||||||
do {
|
|
||||||
i++;
|
|
||||||
nameExist = false;
|
|
||||||
QJsonArray servers = QJsonDocument::fromJson(value("Servers/serversList").toByteArray()).array();
|
|
||||||
for (const QJsonValue &server : servers) {
|
|
||||||
if (server.toObject().value(configKey::description).toString() == QString("Server") + " " + QString::number(i)) {
|
|
||||||
nameExist = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (nameExist);
|
|
||||||
|
|
||||||
return QString("Server") + " " + QString::number(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SecureAppSettingsRepository::setInstallationUuid(const QString &uuid)
|
void SecureAppSettingsRepository::setInstallationUuid(const QString &uuid)
|
||||||
{
|
{
|
||||||
m_settings->setValue("Conf/installationUuid", uuid);
|
m_settings->setValue("Conf/installationUuid", uuid);
|
||||||
|
|||||||
@@ -90,8 +90,6 @@ public:
|
|||||||
bool restoreAppConfig(const QByteArray &cfg);
|
bool restoreAppConfig(const QByteArray &cfg);
|
||||||
void clearSettings();
|
void clearSettings();
|
||||||
|
|
||||||
QString nextAvailableServerName() const;
|
|
||||||
|
|
||||||
QByteArray xraySavedConfigs() const;
|
QByteArray xraySavedConfigs() const;
|
||||||
void setXraySavedConfigs(const QByteArray &data);
|
void setXraySavedConfigs(const QByteArray &data);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonValue>
|
#include <QJsonValue>
|
||||||
|
#include <QSet>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
|
||||||
#include "core/utils/serverConfigUtils.h"
|
#include "core/utils/serverConfigUtils.h"
|
||||||
@@ -32,6 +33,45 @@ QJsonObject embedStorageServerId(const QString &serverId, const QJsonObject &pay
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString storedServerDisplayName(const SecureServersRepository *repository, const QString &serverId)
|
||||||
|
{
|
||||||
|
using Kind = serverConfigUtils::ConfigType;
|
||||||
|
switch (repository->serverKind(serverId)) {
|
||||||
|
case Kind::SelfHostedAdmin:
|
||||||
|
if (const auto cfg = repository->selfHostedAdminConfig(serverId)) {
|
||||||
|
return cfg->displayName;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Kind::SelfHostedUser:
|
||||||
|
if (const auto cfg = repository->selfHostedUserConfig(serverId)) {
|
||||||
|
return cfg->displayName;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Kind::Native:
|
||||||
|
if (const auto cfg = repository->nativeConfig(serverId)) {
|
||||||
|
return cfg->displayName;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Kind::AmneziaPremiumV2:
|
||||||
|
case Kind::AmneziaFreeV3:
|
||||||
|
case Kind::ExternalPremium:
|
||||||
|
if (const auto cfg = repository->apiV2Config(serverId)) {
|
||||||
|
return cfg->displayName;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Kind::AmneziaPremiumV1:
|
||||||
|
case Kind::AmneziaFreeV2:
|
||||||
|
if (const auto cfg = repository->legacyApiConfig(serverId)) {
|
||||||
|
return cfg->displayName;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Kind::Invalid:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
SecureServersRepository::SecureServersRepository(SecureQSettings *settings, QObject *parent)
|
SecureServersRepository::SecureServersRepository(SecureQSettings *settings, QObject *parent)
|
||||||
@@ -153,6 +193,28 @@ void SecureServersRepository::clearServers()
|
|||||||
syncToStorage();
|
syncToStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString SecureServersRepository::nextAvailableServerName() const
|
||||||
|
{
|
||||||
|
QSet<QString> usedNames;
|
||||||
|
usedNames.reserve(m_orderedServerIds.size());
|
||||||
|
|
||||||
|
for (const QString &serverId : m_orderedServerIds) {
|
||||||
|
const QString displayName = storedServerDisplayName(this, serverId);
|
||||||
|
if (!displayName.isEmpty()) {
|
||||||
|
usedNames.insert(displayName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
QString candidate;
|
||||||
|
do {
|
||||||
|
i++;
|
||||||
|
candidate = QStringLiteral("Server %1").arg(i);
|
||||||
|
} while (usedNames.contains(candidate));
|
||||||
|
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
QString SecureServersRepository::addServer(const QString &serverId, const QJsonObject &serverJson, serverConfigUtils::ConfigType kind)
|
QString SecureServersRepository::addServer(const QString &serverId, const QJsonObject &serverJson, serverConfigUtils::ConfigType kind)
|
||||||
{
|
{
|
||||||
const QString id = normalizedOrGeneratedServerId(serverId);
|
const QString id = normalizedOrGeneratedServerId(serverId);
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ public:
|
|||||||
|
|
||||||
void clearServers();
|
void clearServers();
|
||||||
|
|
||||||
|
QString nextAvailableServerName() const;
|
||||||
|
|
||||||
void invalidateCache();
|
void invalidateCache();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|||||||
Reference in New Issue
Block a user