diff --git a/client/3rd/QtSsh/src/ssh/sshconnection.cpp b/client/3rd/QtSsh/src/ssh/sshconnection.cpp index 1cbefa09..6b214121 100644 --- a/client/3rd/QtSsh/src/ssh/sshconnection.cpp +++ b/client/3rd/QtSsh/src/ssh/sshconnection.cpp @@ -940,8 +940,8 @@ void SshConnectionPrivate::connectToHost() this, &SshConnectionPrivate::handleSocketConnected); connect(m_socket, &QIODevice::readyRead, this, &SshConnectionPrivate::handleIncomingData); - connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, - SLOT(handleSocketError())); + connect(m_socket, &QAbstractSocket::errorOccurred, + this, &SshConnectionPrivate::handleSocketError); connect(m_socket, &QAbstractSocket::disconnected, this, &SshConnectionPrivate::handleSocketDisconnected); connect(&m_timeoutTimer, &QTimer::timeout, this, &SshConnectionPrivate::handleTimeout); diff --git a/client/configurators/wireguard_configurator.cpp b/client/configurators/wireguard_configurator.cpp index 2d0a4fd3..c7b29ef5 100644 --- a/client/configurators/wireguard_configurator.cpp +++ b/client/configurators/wireguard_configurator.cpp @@ -50,7 +50,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys() } WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardConfig(const ServerCredentials &credentials, - DockerContainer container, ErrorCode *errorCode) + DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode) { WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys(); connData.host = credentials.hostName; @@ -61,6 +61,49 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon } ErrorCode e = ErrorCode::NoError; + + // Get list of already created clients (only IP addreses) + QString nextIpNumber; + { + QString script = QString("cat %1 | grep AllowedIPs").arg(amnezia::protocols::wireguard::serverConfigPath); + QString stdOut; + auto cbReadStdOut = [&](const QString &data, QSharedPointer proc) { + stdOut += data + "\n"; + }; + + ServerController::runContainerScript(credentials, container, script, cbReadStdOut); + stdOut.replace("AllowedIPs = ", ""); + stdOut.replace("/32", ""); + QStringList ips = stdOut.split("\n", Qt::SkipEmptyParts); + + // Calc next IP address + if (ips.isEmpty()) { + nextIpNumber = "2"; + } + else { + int next = ips.last().split(".").last().toInt() + 1; + if (next > 254) { + if (errorCode) *errorCode = ErrorCode::AddressPoolError; + return connData; + } + nextIpNumber = QString::number(next); + } + } + + QString subnetIp = containerConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress); + { + QStringList l = subnetIp.split(".", Qt::SkipEmptyParts); + if (l.isEmpty()) { + if (errorCode) *errorCode = ErrorCode::AddressPoolError; + return connData; + } + l.removeLast(); + l.append(nextIpNumber); + + connData.clientIP = l.join("."); + } + + // Get keys connData.serverPubKey = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPublicKeyPath, &e); connData.serverPubKey.replace("\n", ""); if (e) { @@ -76,18 +119,15 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon return connData; } - + // Add client to config QString configPart = QString( "[Peer]\n" "PublicKey = %1\n" "PresharedKey = %2\n" - "AllowedIPs = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR\n\n"). + "AllowedIPs = %3/32\n\n"). arg(connData.clientPubKey). - arg(connData.pskKey); - - configPart = ServerController::replaceVars(configPart, ServerController::genVarsForScript(credentials, container)); - - qDebug().noquote() << "Adding wg conf part to server" << configPart; + arg(connData.pskKey). + arg(connData.clientIP); e = ServerController::uploadTextFileToContainer(container, credentials, configPart, protocols::wireguard::serverConfigPath, QSsh::SftpOverwriteMode::SftpAppendToExisting); @@ -116,12 +156,13 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede QString config = ServerController::replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container), ServerController::genVarsForScript(credentials, container, containerConfig)); - ConnectionData connData = prepareWireguardConfig(credentials, container, errorCode); + ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode); if (errorCode && *errorCode) { return ""; } config.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", connData.clientPrivKey); + config.replace("$WIREGUARD_CLIENT_IP", connData.clientIP); config.replace("$WIREGUARD_SERVER_PUBLIC_KEY", connData.serverPubKey); config.replace("$WIREGUARD_PSK", connData.pskKey); @@ -130,6 +171,7 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede jConfig[config_key::hostName] = connData.host; jConfig[config_key::client_priv_key] = connData.clientPrivKey; + jConfig[config_key::client_ip] = connData.clientIP; jConfig[config_key::client_pub_key] = connData.clientPubKey; jConfig[config_key::psk_key] = connData.pskKey; jConfig[config_key::server_pub_key] = connData.serverPubKey; diff --git a/client/configurators/wireguard_configurator.h b/client/configurators/wireguard_configurator.h index 2bd715ad..635c8dce 100644 --- a/client/configurators/wireguard_configurator.h +++ b/client/configurators/wireguard_configurator.h @@ -15,6 +15,7 @@ public: struct ConnectionData { QString clientPrivKey; // client private key QString clientPubKey; // client public key + QString clientIP; // internal client IP address QString serverPubKey; // tls-auth key QString pskKey; // preshared key QString host; // host ip @@ -29,7 +30,7 @@ public: private: static ConnectionData prepareWireguardConfig(const ServerCredentials &credentials, - DockerContainer container, ErrorCode *errorCode = nullptr); + DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr); static ConnectionData genClientKeys(); diff --git a/client/core/defs.h b/client/core/defs.h index 37199d49..bed6b1c3 100644 --- a/client/core/defs.h +++ b/client/core/defs.h @@ -60,6 +60,7 @@ enum ErrorCode OpenVpnAdaptersInUseError, OpenVpnUnknownError, OpenVpnTapAdapterError, + AddressPoolError, // 3rd party utils errors OpenSslFailed, diff --git a/client/core/errorstrings.cpp b/client/core/errorstrings.cpp index ceeb47ab..23e4e36e 100644 --- a/client/core/errorstrings.cpp +++ b/client/core/errorstrings.cpp @@ -45,6 +45,7 @@ QString errorString(ErrorCode code){ // VPN errors case (OpenVpnAdaptersInUseError): return QObject::tr("Can't connect: another VPN connection is active"); case (OpenVpnTapAdapterError): return QObject::tr("Can't setup OpenVPN TAP network adapter"); + case (AddressPoolError): return QObject::tr("VPN pool error: no available addresses"); case(InternalError): default: diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index ad1f48d9..9ab8e3c7 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -667,9 +667,9 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential vars.append({{"$FAKE_WEB_SITE_ADDRESS", cloakConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite) }}); // Wireguard vars - vars.append({{"$WIREGUARD_SUBNET_IP", openvpnConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) }}); - vars.append({{"$WIREGUARD_SUBNET_CIDR", openvpnConfig.value(config_key::subnet_cidr).toString(protocols::wireguard::defaultSubnetCidr) }}); - vars.append({{"$WIREGUARD_SUBNET_MASK", openvpnConfig.value(config_key::subnet_mask).toString(protocols::wireguard::defaultSubnetMask) }}); + vars.append({{"$WIREGUARD_SUBNET_IP", wireguarConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) }}); + vars.append({{"$WIREGUARD_SUBNET_CIDR", wireguarConfig.value(config_key::subnet_cidr).toString(protocols::wireguard::defaultSubnetCidr) }}); + vars.append({{"$WIREGUARD_SUBNET_MASK", wireguarConfig.value(config_key::subnet_mask).toString(protocols::wireguard::defaultSubnetMask) }}); vars.append({{"$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) }}); diff --git a/client/protocols/protocols_defs.h b/client/protocols/protocols_defs.h index 6f8a201e..6eabcd39 100644 --- a/client/protocols/protocols_defs.h +++ b/client/protocols/protocols_defs.h @@ -40,6 +40,7 @@ constexpr char server_priv_key[] = "server_priv_key"; constexpr char server_pub_key[] = "server_pub_key"; constexpr char psk_key[] = "psk_key"; +constexpr char client_ip[] = "client_ip"; // internal ip address constexpr char site[] = "site"; constexpr char block_outside_dns[] = "block_outside_dns"; diff --git a/client/server_scripts/wireguard/template.conf b/client/server_scripts/wireguard/template.conf index ea6c01f7..39274651 100644 --- a/client/server_scripts/wireguard/template.conf +++ b/client/server_scripts/wireguard/template.conf @@ -1,5 +1,5 @@ [Interface] -Address = 10.8.1.2/32 +Address = $WIREGUARD_CLIENT_IP/32 DNS = $PRIMARY_DNS, $SECONDARY_DNS PrivateKey = $WIREGUARD_CLIENT_PRIVATE_KEY diff --git a/client/ui/pages_logic/QrDecoderLogic.cpp b/client/ui/pages_logic/QrDecoderLogic.cpp index 64b0f98f..5933a9e6 100644 --- a/client/ui/pages_logic/QrDecoderLogic.cpp +++ b/client/ui/pages_logic/QrDecoderLogic.cpp @@ -50,9 +50,6 @@ void QrDecoderLogic::onDetectedQrCode(const QString &code) s >> m_chunks[chunkId]; set_receivedChunksCount(m_chunks.size()); - qDebug() << "Received chunks:" << receivedChunksCount() << "/" << chunksCount << "cur" << chunkId << m_chunks[chunkId].size(); - qDebug() << chunkId << m_chunks[chunkId]; - if (m_chunks.size() == totalChunksCount()) { QByteArray data; for (int i = 0; i < totalChunksCount(); ++i) { diff --git a/client/ui/pages_logic/ShareConnectionLogic.cpp b/client/ui/pages_logic/ShareConnectionLogic.cpp index b53822ea..664c8dad 100644 --- a/client/ui/pages_logic/ShareConnectionLogic.cpp +++ b/client/ui/pages_logic/ShareConnectionLogic.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "ShareConnectionLogic.h" @@ -15,6 +16,7 @@ #include "defines.h" #include "core/defs.h" +#include "core/errorstrings.h" #include #include "../uilogic.h" @@ -194,6 +196,12 @@ void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked() ErrorCode e = ErrorCode::NoError; QString cfg = WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, &e); + if (e) { + QMessageBox::warning(nullptr, APPLICATION_NAME, + tr("Error occurred while configuring server.") + "\n" + + errorString(e)); + return; + } cfg = VpnConfigurator::processConfigWithExportSettings(container, Proto::WireGuard, cfg); cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString();