diff --git a/client/configurators/cloak_configurator.cpp b/client/configurators/cloak_configurator.cpp index 50f554dc..1f1726d6 100644 --- a/client/configurators/cloak_configurator.cpp +++ b/client/configurators/cloak_configurator.cpp @@ -13,21 +13,18 @@ CloakConfigurator::CloakConfigurator(std::shared_ptr 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 ""; } diff --git a/client/configurators/cloak_configurator.h b/client/configurators/cloak_configurator.h index c6184805..ff06a5bb 100644 --- a/client/configurators/cloak_configurator.h +++ b/client/configurators/cloak_configurator.h @@ -15,7 +15,7 @@ public: std::shared_ptr 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 diff --git a/client/configurators/ikev2_configurator.cpp b/client/configurators/ikev2_configurator.cpp index 9b702824..d0ef8cea 100644 --- a/client/configurators/ikev2_configurator.cpp +++ b/client/configurators/ikev2_configurator.cpp @@ -22,7 +22,7 @@ Ikev2Configurator::Ikev2Configurator(std::shared_ptr 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 ""; } diff --git a/client/configurators/ikev2_configurator.h b/client/configurators/ikev2_configurator.h index 35c03b19..6f16d6f9 100644 --- a/client/configurators/ikev2_configurator.h +++ b/client/configurators/ikev2_configurator.h @@ -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 diff --git a/client/configurators/openvpn_configurator.cpp b/client/configurators/openvpn_configurator.cpp index 441c15f6..287892d4 100644 --- a/client/configurators/openvpn_configurator.cpp +++ b/client/configurators/openvpn_configurator.cpp @@ -26,13 +26,13 @@ OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr 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 ""; } diff --git a/client/configurators/openvpn_configurator.h b/client/configurators/openvpn_configurator.h index 25230499..588851fe 100644 --- a/client/configurators/openvpn_configurator.h +++ b/client/configurators/openvpn_configurator.h @@ -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); }; diff --git a/client/configurators/shadowsocks_configurator.cpp b/client/configurators/shadowsocks_configurator.cpp index 97503ac4..f9f93867 100644 --- a/client/configurators/shadowsocks_configurator.cpp +++ b/client/configurators/shadowsocks_configurator.cpp @@ -13,17 +13,14 @@ ShadowSocksConfigurator::ShadowSocksConfigurator(std::shared_ptr 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 ""; } diff --git a/client/configurators/shadowsocks_configurator.h b/client/configurators/shadowsocks_configurator.h index be80f169..36b5849f 100644 --- a/client/configurators/shadowsocks_configurator.h +++ b/client/configurators/shadowsocks_configurator.h @@ -14,7 +14,7 @@ public: std::shared_ptr 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 diff --git a/client/configurators/vpn_configurator.cpp b/client/configurators/vpn_configurator.cpp index 1433eeaa..0e663d61 100644 --- a/client/configurators/vpn_configurator.cpp +++ b/client/configurators/vpn_configurator.cpp @@ -26,8 +26,8 @@ VpnConfigurator::VpnConfigurator(std::shared_ptr settings, sshConfigurator = std::shared_ptr(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 &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 VpnConfigurator::getDnsForConfig(int serverIndex) { QPair dns; diff --git a/client/configurators/vpn_configurator.h b/client/configurators/vpn_configurator.h index 47bdc1fd..6f227c37 100644 --- a/client/configurators/vpn_configurator.h +++ b/client/configurators/vpn_configurator.h @@ -20,20 +20,20 @@ class VpnConfigurator : ConfiguratorBase Q_OBJECT public: VpnConfigurator(std::shared_ptr settings, - std::shared_ptr serverController, QObject *parent = nullptr); + std::shared_ptr 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 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 &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 m_serverController; diff --git a/client/configurators/wireguard_configurator.cpp b/client/configurators/wireguard_configurator.cpp index 532d89f6..27e5dc39 100644 --- a/client/configurators/wireguard_configurator.cpp +++ b/client/configurators/wireguard_configurator.cpp @@ -6,7 +6,8 @@ #include #include #include - +#include +#include #include #include @@ -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 &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; +} diff --git a/client/configurators/wireguard_configurator.h b/client/configurators/wireguard_configurator.h index 76790d74..e750e132 100644 --- a/client/configurators/wireguard_configurator.h +++ b/client/configurators/wireguard_configurator.h @@ -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, - std::shared_ptr serverController, QObject *parent = nullptr); + std::shared_ptr 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 &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 diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index 375215b7..e596c32f 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -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 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 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; } diff --git a/client/core/servercontroller.h b/client/core/servercontroller.h index 04ae1a15..b803ee0f 100644 --- a/client/core/servercontroller.h +++ b/client/core/servercontroller.h @@ -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); diff --git a/client/protocols/protocols_defs.h b/client/protocols/protocols_defs.h index c5f15d5b..dd9712b4 100644 --- a/client/protocols/protocols_defs.h +++ b/client/protocols/protocols_defs.h @@ -64,6 +64,8 @@ constexpr char isThirdPartyConfig[] = "isThirdPartyConfig"; constexpr char openvpn[] = "openvpn"; constexpr char wireguard[] = "wireguard"; +constexpr char nativeConfigParametrsStorage[] = "nativeConfigParametrsStorage"; + } namespace protocols { diff --git a/client/ui/pages_logic/ShareConnectionLogic.cpp b/client/ui/pages_logic/ShareConnectionLogic.cpp index 85849391..c4d880f4 100644 --- a/client/ui/pages_logic/ShareConnectionLogic.cpp +++ b/client/ui/pages_logic/ShareConnectionLogic.cpp @@ -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); diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index 4ff67a07..87b6f6a8 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -235,61 +235,69 @@ QMap 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 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; +} diff --git a/client/vpnconnection.h b/client/vpnconnection.h index 3a0d4064..08118fda 100644 --- a/client/vpnconnection.h +++ b/client/vpnconnection.h @@ -38,15 +38,12 @@ public: ErrorCode lastError() const; static QMap 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 m_vpnProtocol; private: + bool shouldProcessLastConfigWithRemoteSettings(const int serverIndex, const Proto proto); + std::shared_ptr m_settings; std::shared_ptr m_configurator; std::shared_ptr m_serverController; diff --git a/deploy/data/allowedIps.txt b/deploy/data/allowedIps.txt deleted file mode 100644 index 8606cf27..00000000 --- a/deploy/data/allowedIps.txt +++ /dev/null @@ -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 diff --git a/docs/configs/containerConfig/wireguard/wireguardContainerConfig.plantuml b/docs/configs/containerConfig/wireguard/wireguardContainerConfig.plantuml index 330bb94d..b28f9675 100644 --- a/docs/configs/containerConfig/wireguard/wireguardContainerConfig.plantuml +++ b/docs/configs/containerConfig/wireguard/wireguardContainerConfig.plantuml @@ -1,4 +1,4 @@ -@startjson +@startjson wireguardContainerConfig { "container : string": "amnezia-wireguard", "wireguard : array": diff --git a/docs/configs/serverConfigImportProcess.plantuml b/docs/configs/serverConfigImportProcess.plantuml index 3c974d2a..06450cb7 100644 --- a/docs/configs/serverConfigImportProcess.plantuml +++ b/docs/configs/serverConfigImportProcess.plantuml @@ -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; diff --git a/docs/configs/serverConfigProcessingOnConnection.plantuml b/docs/configs/serverConfigProcessingOnConnection.plantuml index 7ba6bafa..43589e1d 100644 --- a/docs/configs/serverConfigProcessingOnConnection.plantuml +++ b/docs/configs/serverConfigProcessingOnConnection.plantuml @@ -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 diff --git a/docs/configs/serverConfigWithWriteAccess.plantuml b/docs/configs/serverConfigWithWriteAccess.plantuml index e96e43f0..af62bc1c 100644 --- a/docs/configs/serverConfigWithWriteAccess.plantuml +++ b/docs/configs/serverConfigWithWriteAccess.plantuml @@ -1,4 +1,4 @@ -@startjson +@startjson serverConfigWithWriteAccess { "containers : array": [ diff --git a/docs/configs/serverConfigWithoutWriteAccessV1.plantuml b/docs/configs/serverConfigWithoutWriteAccessV1.plantuml index a940ef1a..079bfc50 100644 --- a/docs/configs/serverConfigWithoutWriteAccessV1.plantuml +++ b/docs/configs/serverConfigWithoutWriteAccessV1.plantuml @@ -1,4 +1,4 @@ -@startjson +@startjson serverConfigWithoutWriteAccessV1 { "containers : array": [ diff --git a/docs/configs/serverConfigWithoutWriteAccessV2.plantuml b/docs/configs/serverConfigWithoutWriteAccessV2.plantuml index 0bd0d8c5..916ac648 100644 --- a/docs/configs/serverConfigWithoutWriteAccessV2.plantuml +++ b/docs/configs/serverConfigWithoutWriteAccessV2.plantuml @@ -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