added parameter nativeConfigParametersStorage to .vpn format config.

- if the parameter is found, parts of the native config for protocols will be downloaded (so far only wireguard) and updated
- minor refactoring of error handling, now reference are used instead of pointers
- removed temp config with allowedIps
This commit is contained in:
vladimir.kuznetsov 2023-01-26 19:44:08 +03:00
parent a382ec0909
commit 5a2a96982a
25 changed files with 240 additions and 161 deletions

View file

@ -13,21 +13,18 @@ CloakConfigurator::CloakConfigurator(std::shared_ptr<Settings> settings, std::sh
}
QString CloakConfigurator::genCloakConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
QString CloakConfigurator::genCloakConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode)
{
ErrorCode e = ErrorCode::NoError;
QString cloakPublicKey = m_serverController->getTextFileFromContainer(container, credentials,
amnezia::protocols::cloak::ckPublicKeyPath, &e);
amnezia::protocols::cloak::ckPublicKeyPath, errorCode);
cloakPublicKey.replace("\n", "");
QString cloakBypassUid = m_serverController->getTextFileFromContainer(container, credentials,
amnezia::protocols::cloak::ckBypassUidKeyPath, &e);
amnezia::protocols::cloak::ckBypassUidKeyPath, errorCode);
cloakBypassUid.replace("\n", "");
if (e) {
if (errorCode) *errorCode = e;
if (errorCode) {
return "";
}

View file

@ -15,7 +15,7 @@ public:
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
QString genCloakConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
const QJsonObject &containerConfig, ErrorCode &errorCode);
};
#endif // CLOAK_CONFIGURATOR_H

View file

@ -22,7 +22,7 @@ Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, std::sh
}
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode)
DockerContainer container, ErrorCode &errorCode)
{
Ikev2Configurator::ConnectionData connData;
connData.host = credentials.hostName;
@ -41,16 +41,16 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
"--extKeyUsage serverAuth,clientAuth -8 \"%1\"")
.arg(connData.clientId);
ErrorCode e = m_serverController->runContainerScript(credentials, container, scriptCreateCert);
errorCode = m_serverController->runContainerScript(credentials, container, scriptCreateCert);
QString scriptExportCert = QString("pk12util -W \"%1\" -d sql:/etc/ipsec.d -n \"%2\" -o \"%3\"")
.arg(connData.password)
.arg(connData.clientId)
.arg(certFileName);
e = m_serverController->runContainerScript(credentials, container, scriptExportCert);
errorCode = m_serverController->runContainerScript(credentials, container, scriptExportCert);
connData.clientCert = m_serverController->getTextFileFromContainer(container, credentials, certFileName, &e);
connData.caCert = m_serverController->getTextFileFromContainer(container, credentials, "/etc/ipsec.d/ca_cert_base64.p12", &e);
connData.clientCert = m_serverController->getTextFileFromContainer(container, credentials, certFileName, errorCode);
connData.caCert = m_serverController->getTextFileFromContainer(container, credentials, "/etc/ipsec.d/ca_cert_base64.p12", errorCode);
qDebug() << "Ikev2Configurator::ConnectionData client cert size:" << connData.clientCert.size();
qDebug() << "Ikev2Configurator::ConnectionData ca cert size:" << connData.caCert.size();
@ -59,12 +59,12 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
}
QString Ikev2Configurator::genIkev2Config(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
DockerContainer container, const QJsonObject &containerConfig, ErrorCode &errorCode)
{
Q_UNUSED(containerConfig)
ConnectionData connData = prepareIkev2Config(credentials, container, errorCode);
if (errorCode && *errorCode) {
if (errorCode) {
return "";
}

View file

@ -23,14 +23,13 @@ public:
};
QString genIkev2Config(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
const QJsonObject &containerConfig, ErrorCode &errorCode);
QString genIkev2Config(const ConnectionData &connData);
QString genMobileConfig(const ConnectionData &connData);
QString genStrongSwanConfig(const ConnectionData &connData);
ConnectionData prepareIkev2Config(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode = nullptr);
ConnectionData prepareIkev2Config(const ServerCredentials &credentials, DockerContainer container, ErrorCode &errorCode);
};
#endif // IKEV2_CONFIGURATOR_H

View file

@ -26,13 +26,13 @@ OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr<Settings> settings, std
}
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode)
DockerContainer container, ErrorCode &errorCode)
{
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
connData.host = credentials.hostName;
if (connData.privKey.isEmpty() || connData.request.isEmpty()) {
if (errorCode) *errorCode = ErrorCode::OpenSslFailed;
errorCode = ErrorCode::OpenSslFailed;
return connData;
}
@ -40,44 +40,43 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
arg(amnezia::protocols::openvpn::clientsDirPath).
arg(connData.clientId);
ErrorCode e = m_serverController->uploadTextFileToContainer(container, credentials, connData.request, reqFileName);
if (e) {
if (errorCode) *errorCode = e;
errorCode = m_serverController->uploadTextFileToContainer(container, credentials, connData.request, reqFileName);
if (errorCode) {
return connData;
}
e = signCert(container, credentials, connData.clientId);
if (e) {
if (errorCode) *errorCode = e;
errorCode = signCert(container, credentials, connData.clientId);
if (errorCode) {
return connData;
}
connData.caCert = m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::caCertPath, &e);
connData.caCert = m_serverController->getTextFileFromContainer(container, credentials,
amnezia::protocols::openvpn::caCertPath, errorCode);
connData.clientCert = m_serverController->getTextFileFromContainer(container, credentials,
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), &e);
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), errorCode);
if (e) {
if (errorCode) *errorCode = e;
if (errorCode) {
return connData;
}
connData.taKey = m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::taKeyPath, &e);
connData.taKey = m_serverController->getTextFileFromContainer(container, credentials,
amnezia::protocols::openvpn::taKeyPath, errorCode);
if (connData.caCert.isEmpty() || connData.clientCert.isEmpty() || connData.taKey.isEmpty()) {
if (errorCode) *errorCode = ErrorCode::RemoteProcessCrashError;
errorCode = ErrorCode::RemoteProcessCrashError;
}
return connData;
}
QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
DockerContainer container, const QJsonObject &containerConfig, ErrorCode &errorCode)
{
QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::openvpn_template, container),
m_serverController->genVarsForScript(credentials, container, containerConfig));
ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode);
if (errorCode && *errorCode) {
if (errorCode) {
return "";
}

View file

@ -25,7 +25,7 @@ public:
};
QString genOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
const QJsonObject &containerConfig, ErrorCode &errorCode);
QString processConfigWithLocalSettings(QString jsonConfig);
QString processConfigWithExportSettings(QString jsonConfig);
@ -37,7 +37,7 @@ private:
ConnectionData createCertRequest();
ConnectionData prepareOpenVpnConfig(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode = nullptr);
DockerContainer container, ErrorCode &errorCode);
};

View file

@ -13,17 +13,14 @@ ShadowSocksConfigurator::ShadowSocksConfigurator(std::shared_ptr<Settings> setti
}
QString ShadowSocksConfigurator::genShadowSocksConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
QString ShadowSocksConfigurator::genShadowSocksConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode)
{
ErrorCode e = ErrorCode::NoError;
QString ssKey = m_serverController->getTextFileFromContainer(container, credentials,
amnezia::protocols::shadowsocks::ssKeyPath, &e);
amnezia::protocols::shadowsocks::ssKeyPath, errorCode);
ssKey.replace("\n", "");
if (e) {
if (errorCode) *errorCode = e;
if (errorCode) {
return "";
}

View file

@ -14,7 +14,7 @@ public:
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
QString genShadowSocksConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
const QJsonObject &containerConfig, ErrorCode &errorCode);
};
#endif // SHADOWSOCKS_CONFIGURATOR_H

View file

@ -26,8 +26,8 @@ VpnConfigurator::VpnConfigurator(std::shared_ptr<Settings> settings,
sshConfigurator = std::shared_ptr<SshConfigurator>(new SshConfigurator(settings, serverController, this));
}
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode)
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, Proto proto, ErrorCode &errorCode)
{
switch (proto) {
case Proto::OpenVpn:
@ -50,6 +50,25 @@ QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentia
}
}
ErrorCode VpnConfigurator::processLastConfigWithRemoteSettings(QMap<Proto, QString> &lastVpnConfigs,
const int serverIndex, const Proto proto)
{
switch (proto) {
case Proto::OpenVpn:
return ErrorCode::NotImplementedError;
case Proto::ShadowSocks:
return ErrorCode::NotImplementedError;
case Proto::Cloak:
return ErrorCode::NotImplementedError;
case Proto::WireGuard:
return wireguardConfigurator->processLastConfigWithRemoteSettings(lastVpnConfigs, serverIndex);
case Proto::Ikev2:
return ErrorCode::NotImplementedError;
default:
return ErrorCode::ConfigMissing;
}
}
QPair<QString, QString> VpnConfigurator::getDnsForConfig(int serverIndex)
{
QPair<QString, QString> dns;

View file

@ -20,20 +20,20 @@ class VpnConfigurator : ConfiguratorBase
Q_OBJECT
public:
VpnConfigurator(std::shared_ptr<Settings> settings,
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode = nullptr);
const QJsonObject &containerConfig, Proto proto, ErrorCode &errorCode);
QPair<QString, QString> getDnsForConfig(int serverIndex);
QString &processConfigWithDnsSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
QString &processConfigWithLocalSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
QString &processConfigWithExportSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
ErrorCode processLastConfigWithRemoteSettings(QMap<Proto, QString> &lastVpnConfigs, const int serverIndex, const Proto proto);
// workaround for containers which is not support normal configaration
void updateContainerConfigAfterInstallation(DockerContainer container,
QJsonObject &containerConfig, const QString &stdOut);
void updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig, const QString &stdOut);
std::shared_ptr<ServerController> m_serverController;

View file

@ -6,7 +6,8 @@
#include <QDebug>
#include <QTemporaryFile>
#include <QJsonDocument>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <openssl/rand.h>
#include <openssl/rsa.h>
@ -59,18 +60,16 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
}
WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
DockerContainer container, const QJsonObject &containerConfig, ErrorCode &errorCode)
{
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
connData.host = credentials.hostName;
if (connData.clientPrivKey.isEmpty() || connData.clientPubKey.isEmpty()) {
if (errorCode) *errorCode = ErrorCode::InternalError;
errorCode = ErrorCode::InternalError;
return connData;
}
ErrorCode e = ErrorCode::NoError;
// Get list of already created clients (only IP addreses)
QString nextIpNumber;
{
@ -80,9 +79,8 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
stdOut += data + "\n";
};
e = m_serverController->runContainerScript(credentials, container, script, cbReadStdOut);
if (errorCode && e) {
*errorCode = e;
errorCode = m_serverController->runContainerScript(credentials, container, script, cbReadStdOut);
if (errorCode) {
return connData;
}
@ -97,7 +95,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
else {
int next = ips.last().split(".").last().toInt() + 1;
if (next > 254) {
if (errorCode) *errorCode = ErrorCode::AddressPoolError;
errorCode = ErrorCode::AddressPoolError;
return connData;
}
nextIpNumber = QString::number(next);
@ -108,7 +106,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
{
QStringList l = subnetIp.split(".", Qt::SkipEmptyParts);
if (l.isEmpty()) {
if (errorCode) *errorCode = ErrorCode::AddressPoolError;
errorCode = ErrorCode::AddressPoolError;
return connData;
}
l.removeLast();
@ -118,18 +116,19 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
}
// Get keys
connData.serverPubKey = m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPublicKeyPath, &e);
connData.serverPubKey = m_serverController->getTextFileFromContainer(container, credentials,
amnezia::protocols::wireguard::serverPublicKeyPath,
errorCode);
connData.serverPubKey.replace("\n", "");
if (e) {
if (errorCode) *errorCode = e;
if (errorCode) {
return connData;
}
connData.pskKey = m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPskKeyPath, &e);
connData.pskKey = m_serverController->getTextFileFromContainer(container, credentials,
amnezia::protocols::wireguard::serverPskKeyPath, errorCode);
connData.pskKey.replace("\n", "");
if (e) {
if (errorCode) *errorCode = e;
if (errorCode) {
return connData;
}
@ -143,15 +142,15 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
arg(connData.pskKey).
arg(connData.clientIP);
e = m_serverController->uploadTextFileToContainer(container, credentials, configPart,
protocols::wireguard::serverConfigPath, QSsh::SftpOverwriteMode::SftpAppendToExisting);
errorCode = m_serverController->uploadTextFileToContainer(container, credentials, configPart,
protocols::wireguard::serverConfigPath,
QSsh::SftpOverwriteMode::SftpAppendToExisting);
if (e) {
if (errorCode) *errorCode = e;
if (errorCode) {
return connData;
}
e = m_serverController->runScript(credentials,
errorCode = m_serverController->runScript(credentials,
m_serverController->replaceVars("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip /opt/amnezia/wireguard/wg0.conf)'",
m_serverController->genVarsForScript(credentials, container)));
@ -159,13 +158,13 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
}
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
DockerContainer container, const QJsonObject &containerConfig, ErrorCode &errorCode)
{
QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container),
m_serverController->genVarsForScript(credentials, container, containerConfig));
ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode);
if (errorCode && *errorCode) {
if (errorCode) {
return "";
}
@ -206,3 +205,49 @@ QString WireguardConfigurator::processConfigWithExportSettings(QString config)
return config;
}
ErrorCode WireguardConfigurator::processLastConfigWithRemoteSettings(QMap<Proto, QString> &lastVpnConfigs, const int serverIndex)
{
QString allowedIps;
ErrorCode errorCode = ErrorCode::NoError;
QNetworkAccessManager manager;
QObject::connect(&manager, &QNetworkAccessManager::finished, this, [this, &allowedIps, &errorCode](QNetworkReply *reply) {
if (reply->error()) {
qDebug() << reply->errorString();
errorCode = ErrorCode::InternalError;
emit remoteProcessingFinished();
return;
}
allowedIps = reply->readAll();
emit remoteProcessingFinished();
});
QNetworkRequest request;
const QJsonObject serverSettings = m_settings->server(serverIndex);
request.setUrl(serverSettings.value(config_key::nativeConfigParametrsStorage).toString());
manager.get(request);
QEventLoop wait;
QObject::connect(this, &WireguardConfigurator::remoteProcessingFinished, &wait, &QEventLoop::quit);
wait.exec();
if (errorCode == ErrorCode::NoError) {
allowedIps = allowedIps.trimmed();
QString config = lastVpnConfigs.value(Proto::WireGuard);
QJsonObject lastConfigJson = QJsonDocument::fromJson(config.toUtf8()).object();
QStringList configLines = lastConfigJson.value(config_key::config).toString().split("\n");
for (auto &line : configLines) {
if (line.contains("AllowedIPs")) {
line = allowedIps;
}
}
QJsonObject newConfigJson;
newConfigJson[config_key::config] = configLines.join("\n");
lastVpnConfigs[Proto::WireGuard] = QString(QJsonDocument(newConfigJson).toJson());;
return ErrorCode::NoError;
}
return errorCode;
}

View file

@ -7,12 +7,12 @@
#include "configurator_base.h"
#include "core/defs.h"
class WireguardConfigurator : ConfiguratorBase
class WireguardConfigurator : public ConfiguratorBase
{
Q_OBJECT
public:
WireguardConfigurator(std::shared_ptr<Settings> settings,
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
struct ConnectionData {
QString clientPrivKey; // client private key
@ -24,17 +24,22 @@ public:
};
QString genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
const QJsonObject &containerConfig, ErrorCode &errorCode);
QString processConfigWithLocalSettings(QString config);
QString processConfigWithExportSettings(QString config);
ErrorCode processLastConfigWithRemoteSettings(QMap<Proto, QString> &lastVpnConfigs, const int serverIndex);
private:
ConnectionData prepareWireguardConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
DockerContainer container, const QJsonObject &containerConfig,
ErrorCode &errorCode);
ConnectionData genClientKeys();
signals:
void remoteProcessingFinished();
};
#endif // WIREGUARD_CONFIGURATOR_H

View file

@ -220,9 +220,9 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
}
QByteArray ServerController::getTextFileFromContainer(DockerContainer container,
const ServerCredentials &credentials, const QString &path, ErrorCode *errorCode)
const ServerCredentials &credentials, const QString &path, ErrorCode &errorCode)
{
if (errorCode) *errorCode = ErrorCode::NoError;
errorCode = ErrorCode::NoError;
QString script = QString("sudo docker exec -i %1 sh -c \"xxd -p \'%2\'\"").
arg(ContainerProps::containerToString(container)).arg(path);
@ -231,14 +231,14 @@ QByteArray ServerController::getTextFileFromContainer(DockerContainer container,
SshConnection *client = connectToHost(sshParams(credentials));
if (client->state() != SshConnection::State::Connected) {
if (errorCode) *errorCode = fromSshConnectionErrorCode(client->errorState());
errorCode = fromSshConnectionErrorCode(client->errorState());
return {};
}
QSharedPointer<SshRemoteProcess> proc = client->createRemoteProcess(script.toUtf8());
if (!proc) {
qCritical() << "Failed to create SshRemoteProcess, breaking.";
if (errorCode) *errorCode = ErrorCode::SshRemoteProcessCreationError;
errorCode = ErrorCode::SshRemoteProcessCreationError;
return {};
}
@ -263,26 +263,26 @@ QByteArray ServerController::getTextFileFromContainer(DockerContainer container,
// }
if (SshRemoteProcess::ExitStatus(exitStatus) != QSsh::SshRemoteProcess::ExitStatus::NormalExit) {
if (errorCode) *errorCode = fromSshProcessExitStatus(exitStatus);
errorCode = fromSshProcessExitStatus(exitStatus);
}
if (errorCode) *errorCode = ErrorCode::NoError;
errorCode = ErrorCode::NoError;
return QByteArray::fromHex(proc->readAllStandardOutput());
}
ErrorCode ServerController::checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials)
{
QString caCert = ServerController::getTextFileFromContainer(container,
credentials, protocols::openvpn::caCertPath);
QString taKey = ServerController::getTextFileFromContainer(container,
credentials, protocols::openvpn::taKeyPath);
if (!caCert.isEmpty() && !taKey.isEmpty()) {
return ErrorCode::NoError;
}
else {
ErrorCode errorCode = ErrorCode::NoError;
QString caCert = ServerController::getTextFileFromContainer(container, credentials, protocols::openvpn::caCertPath, errorCode);
if (caCert.isEmpty() || errorCode != ErrorCode::NoError) {
return ErrorCode::ServerCheckFailed;
}
QString taKey = ServerController::getTextFileFromContainer(container, credentials, protocols::openvpn::taKeyPath, errorCode);
if (taKey.isEmpty() || errorCode != ErrorCode::NoError) {
return ErrorCode::ServerCheckFailed;
}
return ErrorCode::NoError;
}
ErrorCode ServerController::uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath,
@ -756,7 +756,7 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
return vars;
}
QString ServerController::checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode)
QString ServerController::checkSshConnection(const ServerCredentials &credentials, ErrorCode &errorCode)
{
QString stdOut;
auto cbReadStdOut = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
@ -766,10 +766,7 @@ QString ServerController::checkSshConnection(const ServerCredentials &credential
stdOut += data + "\n";
};
ErrorCode e = runScript(credentials,
amnezia::scriptData(SharedScriptType::check_connection), cbReadStdOut, cbReadStdErr);
if (errorCode) *errorCode = e;
errorCode = runScript(credentials, amnezia::scriptData(SharedScriptType::check_connection), cbReadStdOut, cbReadStdErr);
return stdOut;
}

View file

@ -54,7 +54,7 @@ public:
QSsh::SftpOverwriteMode overwriteMode = QSsh::SftpOverwriteMode::SftpOverwriteExisting);
QByteArray getTextFileFromContainer(DockerContainer container,
const ServerCredentials &credentials, const QString &path, ErrorCode *errorCode = nullptr);
const ServerCredentials &credentials, const QString &path, ErrorCode &errorCode);
ErrorCode setupServerFirewall(const ServerCredentials &credentials);
@ -70,7 +70,7 @@ public:
Vars genVarsForScript(const ServerCredentials &credentials, DockerContainer container = DockerContainer::None, const QJsonObject &config = QJsonObject());
QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr);
QString checkSshConnection(const ServerCredentials &credentials, ErrorCode &errorCode);
QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
void setCancelInstallation(const bool cancel);

View file

@ -64,6 +64,8 @@ constexpr char isThirdPartyConfig[] = "isThirdPartyConfig";
constexpr char openvpn[] = "openvpn";
constexpr char wireguard[] = "wireguard";
constexpr char nativeConfigParametrsStorage[] = "nativeConfigParametrsStorage";
}
namespace protocols {

View file

@ -81,12 +81,12 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
QJsonObject containerConfig = m_settings->containerConfig(serverIndex, container);
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
ErrorCode e = ErrorCode::NoError;
ErrorCode errorCode = ErrorCode::NoError;
for (Proto p: ContainerProps::protocolsForContainer(container)) {
QJsonObject protoConfig = m_settings->protocolConfig(serverIndex, container, p);
QString cfg = m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, p, &e);
if (e) {
QString cfg = m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, p, errorCode);
if (errorCode) {
cfg = "Error generating config";
break;
}
@ -95,7 +95,7 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
}
QByteArray ba;
if (!e) {
if (!errorCode) {
serverConfig = m_settings->server(serverIndex);
serverConfig.remove(config_key::userName);
serverConfig.remove(config_key::password);
@ -133,8 +133,8 @@ void ShareConnectionLogic::onPushButtonShareOpenVpnGenerateClicked()
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError;
QString cfg = m_configurator->openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig, &e);
ErrorCode errorCode = ErrorCode::NoError;
QString cfg = m_configurator->openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig, errorCode);
cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::OpenVpn, cfg);
set_textEditShareOpenVpnCodeText(QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString());
@ -152,8 +152,8 @@ void ShareConnectionLogic::onPushButtonShareShadowSocksGenerateClicked()
if (cfg.isEmpty()) {
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError;
cfg = m_configurator->shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, &e);
ErrorCode errorCode = ErrorCode::NoError;
cfg = m_configurator->shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, errorCode);
}
QJsonObject ssConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
@ -196,8 +196,8 @@ void ShareConnectionLogic::onPushButtonShareCloakGenerateClicked()
if (cfg.isEmpty()) {
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError;
cfg = m_configurator->cloakConfigurator->genCloakConfig(credentials, container, containerConfig, &e);
ErrorCode errorCode = ErrorCode::NoError;
cfg = m_configurator->cloakConfigurator->genCloakConfig(credentials, container, containerConfig, errorCode);
}
QJsonObject cloakConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
@ -215,12 +215,12 @@ void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked()
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError;
QString cfg = m_configurator->wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, &e);
if (e) {
ErrorCode errorCode = ErrorCode::NoError;
QString cfg = m_configurator->wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, errorCode);
if (errorCode) {
QMessageBox::warning(nullptr, APPLICATION_NAME,
tr("Error occurred while configuring server.") + "\n" +
errorString(e));
errorString(errorCode));
return;
}
cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::WireGuard, cfg);
@ -240,7 +240,8 @@ void ShareConnectionLogic::onPushButtonShareIkev2GenerateClicked()
DockerContainer container = uiLogic()->selectedDockerContainer;
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
Ikev2Configurator::ConnectionData connData = m_configurator->ikev2Configurator->prepareIkev2Config(credentials, container);
ErrorCode errorCode = ErrorCode::NoError;
Ikev2Configurator::ConnectionData connData = m_configurator->ikev2Configurator->prepareIkev2Config(credentials, container, errorCode);
QString cfg = m_configurator->ikev2Configurator->genIkev2Config(connData);
cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::Ikev2, cfg);

View file

@ -235,61 +235,69 @@ QMap<Proto, QString> VpnConnection::getLastVpnConfig(const QJsonObject &containe
return configs;
}
QString VpnConnection::createVpnConfigurationForProto(int serverIndex,
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, Proto proto,
ErrorCode *errorCode)
QString VpnConnection::createVpnConfigurationForProto(int serverIndex, const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig,
Proto proto, ErrorCode &errorCode)
{
ErrorCode e = ErrorCode::NoError;
QMap<Proto, QString> lastVpnConfig = getLastVpnConfig(containerConfig);
QString configData;
if (lastVpnConfig.contains(proto)) {
if (shouldProcessLastConfigWithRemoteSettings(serverIndex, proto)) {
errorCode = m_configurator->processLastConfigWithRemoteSettings(lastVpnConfig, serverIndex, proto);
if (errorCode) {
return "";
}
configData = lastVpnConfig.value(proto);
if (serverIndex >= 0) {
QJsonObject protoObject = m_settings->protocolConfig(serverIndex, container, proto);
protoObject.insert(config_key::last_config, configData);
m_settings->setProtocolConfig(serverIndex, container, proto, protoObject);
}
configData = m_configurator->processConfigWithLocalSettings(serverIndex, container, proto, configData);
} else if (lastVpnConfig.contains(proto)) {
configData = lastVpnConfig.value(proto);
configData = m_configurator->processConfigWithLocalSettings(serverIndex, container, proto, configData);
}
else {
configData = m_configurator->genVpnProtocolConfig(credentials,
container, containerConfig, proto, &e);
} else if (credentials.isValid()) {
configData = m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, proto, errorCode);
QString configDataBeforeLocalProcessing = configData;
configData = m_configurator->processConfigWithLocalSettings(serverIndex, container, proto, configData);
if (errorCode && e) {
*errorCode = e;
if (errorCode) {
return "";
}
if (serverIndex >= 0) {
qDebug() << "VpnConnection::createVpnConfiguration: saving config for server #" << serverIndex << container << proto;
QJsonObject protoObject = m_settings->protocolConfig(serverIndex, container, proto);
protoObject.insert(config_key::last_config, configDataBeforeLocalProcessing);
m_settings->setProtocolConfig(serverIndex, container, proto, protoObject);
}
} else {
errorCode = ErrorCode::InternalError;
return "";
}
if (errorCode) *errorCode = e;
return configData;
}
QJsonObject VpnConnection::createVpnConfiguration(int serverIndex,
const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode)
const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode)
{
ErrorCode e = ErrorCode::NoError;
QJsonObject vpnConfiguration;
for (ProtocolEnumNS::Proto proto : ContainerProps::protocolsForContainer(container)) {
QJsonObject vpnConfigData = QJsonDocument::fromJson(
createVpnConfigurationForProto(
serverIndex, credentials, container, containerConfig, proto, &e).toUtf8()).
object();
if (e) {
if (errorCode) *errorCode = e;
createVpnConfigurationForProto(serverIndex, credentials,
container, containerConfig,
proto, errorCode).toUtf8()).object();
if (errorCode) {
return {};
}
@ -337,10 +345,10 @@ void VpnConnection::connectToVpn(int serverIndex,
m_vpnProtocol.reset();
}
ErrorCode e = ErrorCode::NoError;
ErrorCode errorCode = ErrorCode::NoError;
m_vpnConfiguration = createVpnConfiguration(serverIndex, credentials, container, containerConfig);
if (e) {
m_vpnConfiguration = createVpnConfiguration(serverIndex, credentials, container, containerConfig, errorCode);
if (errorCode) {
emit connectionStateChanged(VpnProtocol::Error);
return;
}
@ -379,8 +387,8 @@ void VpnConnection::connectToVpn(int serverIndex,
m_serverController->disconnectFromHost(credentials);
e = m_vpnProtocol.data()->start();
if (e) emit VpnProtocol::Error;
errorCode = m_vpnProtocol.data()->start();
if (errorCode) emit VpnProtocol::Error;
}
QString VpnConnection::bytesPerSecToText(quint64 bytes)
@ -443,3 +451,14 @@ bool VpnConnection::isDisconnected() const
return m_vpnProtocol.data()->isDisconnected();
}
bool VpnConnection::shouldProcessLastConfigWithRemoteSettings(const int serverIndex, const Proto proto)
{
const QJsonObject serverSettings = m_settings->server(serverIndex);
if (serverSettings.contains(config_key::nativeConfigParametrsStorage)) {
if (proto == Proto::WireGuard) {
return true;
}
}
return false;
}

View file

@ -38,15 +38,12 @@ public:
ErrorCode lastError() const;
static QMap<Proto, QString> getLastVpnConfig(const QJsonObject &containerConfig);
QString createVpnConfigurationForProto(int serverIndex,
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, Proto proto,
ErrorCode *errorCode = nullptr);
QJsonObject createVpnConfiguration(int serverIndex,
const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
QString createVpnConfigurationForProto(int serverIndex, const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig,
Proto proto, ErrorCode &errorCode);
QJsonObject createVpnConfiguration(int serverIndex, const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode &errorCode);
bool isConnected() const;
bool isDisconnected() const;
@ -86,6 +83,8 @@ protected:
QSharedPointer<VpnProtocol> m_vpnProtocol;
private:
bool shouldProcessLastConfigWithRemoteSettings(const int serverIndex, const Proto proto);
std::shared_ptr<Settings> m_settings;
std::shared_ptr<VpnConfigurator> m_configurator;
std::shared_ptr<ServerController> m_serverController;

View file

@ -1 +0,0 @@
AllowedIPs = 1.1.1.0/24,1.0.0.0/24,31.13.0.0/16,157.240.0.0/16,108.174.0.0/16,69.63.0.0/16,66.220.144.0/20,179.60.192.0/22,103.4.96.0/22,45.64.40.0/22,204.15.20.0/22,74.119.76.0/22,185.60.216.0/22,185.89.216.0/22,102.132.96.0/20,147.75.208.0/20,69.171.224.0/19,173.252.64.0/18,91.225.248.0/24,185.63.144.0/24,108.174.0.0/16,13.104.0.0/14,179.43.149.0/24,217.195.153.0/24,91.211.91.0/24,151.101.0.0/16,91.227.34.0/24,151.115.45.0/24,163.172.74.0/24,88.212.244.0/24,151.115.46.0/23,151.115.57.0/24,88.212.240.0/24,185.137.235.0/24,185.71.67.0/24,212.58.249.0/24,185.70.40.0/21,18.195.178.0/24,54.93.56.0/24,35.159.24.0/24,3.127.229.0/24,51.15.103.0/24,5.61.58.0/24,37.1.207.0/24,81.17.19.0/24,82.202.255.0/24,185.124.11.0/24,74.125.196.0/24,145.14.151.0/24,178.248.236.0/24,62.115.252.0/24,80.239.137.0/24,148.251.28.0/24,152.199.21.0/24,3.127.12.0/24,3.122.61.0/24,81.92.228.0/24,185.12.144.0/24,51.75.145.0/24,95.217.91.0/24,145.239.2.0/24,54.38.195.0/24,95.217.118.0/24,95.141.32.0/24,51.77.52.0/24,5.188.73.0/24,147.135.138.0/24,195.137.240.0/24,23.193.18.0/24,185.215.4.0/24,194.55.30.0/24,194.55.26.0/24,212.58.237.0/24,212.58.233.0/24,192.229.220.0/24,68.232.34.0/24,192.229.233.0/24,184.51.232.0/24,184.29.192.0/24,62.115.252.0/24,5.61.49.0/24,144.2.8.0/21,80.239.137.0/24,151.139.128.0/24,216.92.111.0/24,3.224.128.0/24,79.98.25.0/24,91.234.200.0/24,142.251.36.0/24,142.250.179.0/24,172.217.168.202/32,216.58.214.10/32,216.58.208.106/32,142.251.39.106/32,2.18.12.0/24,23.32.0.0/11,104.64.0.0/10,104.16.0.0/12,95.100.64.0/20,96.16.0.0/15,172.64.0.0/13,23.0.0.0/12,184.84.0.0/14,44.192.0.0/10,84.53.184.0/21,184.50.0.0/15,2.21.192.0/20,15.236.0.0/14,23.64.0.0/14,184.24.0.0/13,2.19.176.0/20,92.123.248.0/22,188.114.96.0/22,65.8.0.0/14,52.84.0.0/14,52.88.0.0/14,52.92.0.0/14,108.156.0.0/14,13.24.0.0/13,13.32.0.0/12,13.48.0.0/13,13.56.0.0/14,18.64.0.0/14,52.222.0.0/16,34.192.0.0/10,107.20.0.0/14,143.204.0.0/16,52.216.0.0/14,52.208.0.0/13,52.223.0.0/17,52.222.0.0/16,52.192.0.0/12,52.220.0.0/15,52.223.128.0/18,50.16.0.0/14,54.208.0.0/15,34.88.241.156/32,179.43.150.0/24,103.252.112.0/22,104.244.40.0/21,185.45.5.0/24,185.45.6.0/23,188.64.224.0/21,192.133.76.0/22,192.44.69.0/24,199.16.156.0/22,199.59.148.0/22,199.96.56.0/21,202.160.128.0/22,209.237.192.0/19,69.195.160.0/19,64.63.0.0/18,93.184.220.0/22

View file

@ -1,4 +1,4 @@
@startjson
@startjson wireguardContainerConfig
{
"container : string": "amnezia-wireguard",
"wireguard : array":

View file

@ -9,7 +9,7 @@ if (server config contains valid server credentials || containers) then (yes)
if (user clicked continue import) then (yes)
:append server config to app internal settings;
else (no)
:do nothing;
:remove imported config;
endif
else (no)
:show error;

View file

@ -5,12 +5,13 @@ start
:createVpnConfiguration();
:createVpnConfigurationForProto();
if (serverConfig.contains(lastConfigStorage)) then (yes)
:download native config from lastConfigStorage;
if (serverConfig.contains(nativeConfigParametrsStorage)) then (yes)
:update last_config with data from nativeConfigParametrsStorage;
else if (serverConfig.contains(last_config)) then (yes)
:do nothing special;
else if (serverConfig.contains(admin credentials)) then (yes)
:generate new native config;
:save config in last_config;
else
:return empty config and error;
stop

View file

@ -1,4 +1,4 @@
@startjson
@startjson serverConfigWithWriteAccess
{
"containers : array":
[

View file

@ -1,4 +1,4 @@
@startjson
@startjson serverConfigWithoutWriteAccessV1
{
"containers : array":
[

View file

@ -1,4 +1,4 @@
@startjson
@startjson serverConfigWithoutWriteAccessV2
{
"containers : array":
[
@ -27,6 +27,6 @@
"dns2 : string": "dns address",
"hostName : string": "server address",
"version : number": "2",
"lastConfigStorage : string": "storage address"
"nativeConfigParametrsStorage : string": "storage address"
}
@endjson