added saving the list of clients for wireguard

- added error handling when getting/saving a list of clients
This commit is contained in:
vladimir.kuznetsov 2023-01-11 20:36:47 +03:00
parent 8c137ecc52
commit a7030cdcb9
5 changed files with 87 additions and 53 deletions

View file

@ -798,32 +798,44 @@ SshConnection *ServerController::connectToHost(const SshConnectionParameters &ss
ErrorCode ServerController::getClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, QJsonObject &clietns) ErrorCode ServerController::getClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, QJsonObject &clietns)
{ {
ErrorCode error = ErrorCode::NoError;
QString stdOut; QString stdOut;
auto cbReadStdOut = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) { auto cbReadStdOut = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
stdOut += data + "\n"; stdOut += data + "\n";
}; };
ErrorCode error = ErrorCode::NoError; auto mainProtocolString = ProtocolProps::protoToString(mainProtocol);
const QString clientsTableFile = QString("opt/amnezia/%1/clientsTable").arg(mainProtocolString);
QByteArray clientsTableString = getTextFileFromContainer(container, credentials, clientsTableFile, &error);
if (error != ErrorCode::NoError) {
return error;
}
QJsonObject clientsTable = QJsonDocument::fromJson(clientsTableString).object();
int count = 0;
if (mainProtocol == Proto::OpenVpn) { if (mainProtocol == Proto::OpenVpn) {
error = runScript(credentials, const QString getOpenVpnClientsList = "sudo docker exec -i $CONTAINER_NAME bash -c 'ls /opt/amnezia/openvpn/pki/issued'";
replaceVars(QString("sudo docker exec -i $CONTAINER_NAME bash -c 'ls /opt/amnezia/openvpn/pki/issued'"), error = runScript(credentials, replaceVars(getOpenVpnClientsList, genVarsForScript(credentials, container)), cbReadStdOut);
genVarsForScript(credentials, container)), cbReadStdOut); if (error != ErrorCode::NoError) {
// TODO error processing return error;
}
if (!stdOut.isEmpty()) { if (!stdOut.isEmpty()) {
QStringList certsIds = stdOut.split("\n", Qt::SkipEmptyParts); QStringList certsIds = stdOut.split("\n", Qt::SkipEmptyParts);
certsIds.removeAll("AmneziaReq.crt"); certsIds.removeAll("AmneziaReq.crt");
QByteArray clientsTableString = getTextFileFromContainer(container, credentials, "opt/amnezia/openvpn/clientsTable");
QJsonObject clientsTable = QJsonDocument::fromJson(clientsTableString).object();
int count = 0;
for (auto &openvpnCertId : certsIds) { for (auto &openvpnCertId : certsIds) {
openvpnCertId.replace(".crt", ""); openvpnCertId.replace(".crt", "");
if (!clientsTable.contains(openvpnCertId)) { if (!clientsTable.contains(openvpnCertId)) {
stdOut.clear(); stdOut.clear();
error = runScript(credentials, const QString getOpenVpnCertData = QString("sudo docker exec -i $CONTAINER_NAME bash -c 'cat /opt/amnezia/openvpn/pki/issued/%1.crt'")
replaceVars(QString("sudo docker exec -i $CONTAINER_NAME bash -c 'cat /opt/amnezia/openvpn/pki/issued/%1.crt'").arg(openvpnCertId), .arg(openvpnCertId);
genVarsForScript(credentials, container)), cbReadStdOut); error = runScript(credentials, replaceVars(getOpenVpnCertData, genVarsForScript(credentials, container)), cbReadStdOut);
// TODO error processing if (error != ErrorCode::NoError) {
return error;
}
QJsonObject client; QJsonObject client;
client["openvpnCertId"] = openvpnCertId; client["openvpnCertId"] = openvpnCertId;
client["clientName"] = QString("Client %1").arg(count); client["clientName"] = QString("Client %1").arg(count);
@ -832,54 +844,53 @@ ErrorCode ServerController::getClientsList(const ServerCredentials &credentials,
count++; count++;
} }
} }
QByteArray newClientsTableString = QJsonDocument(clientsTable).toJson();
if (clientsTableString != newClientsTableString) {
error = uploadTextFileToContainer(container, credentials, newClientsTableString, "opt/amnezia/openvpn/clientsTable");
}
// TODO error processing
clietns = clientsTable;
} }
} else if (mainProtocol == Proto::WireGuard) { } else if (mainProtocol == Proto::WireGuard) {
QString wireguardConfigString = getTextFileFromContainer(container, credentials, "opt/amnezia/wireguard/wg0.conf"); const QString wireGuardConfigFile = "opt/amnezia/wireguard/wg0.conf";
QString wireguardConfigString = getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error);
auto configSections = wireguardConfigString.split("[", Qt::SkipEmptyParts); if (error != ErrorCode::NoError) {
QJsonObject clientsTable; return error;
int count = 0;
for (const auto &section : configSections) {
auto configLines = section.split("\n", Qt::SkipEmptyParts);
if (!configLines.contains("Peer]")) {
continue;
} }
QJsonObject client;
auto configLines = wireguardConfigString.split("\n", Qt::SkipEmptyParts);
QStringList wireguardKeys;
for (const auto &line : configLines) { for (const auto &line : configLines) {
auto configPair = line.split(" = ", Qt::SkipEmptyParts); auto configPair = line.split(" = ", Qt::SkipEmptyParts);
if (configPair.front() == "# Name") { if (configPair.front() == "PublicKey") {
client["clientName"] = configPair.size() == 2 ? configPair.back() : ""; wireguardKeys.push_back(configPair.back());
} else if (configPair.front() == "PublicKey") {
client["wireguardPublicKey"] = configPair.back();
} }
} }
if (client["clientName"].isNull()) {
for (auto &wireguardKey : wireguardKeys) {
if (!clientsTable.contains(wireguardKey)) {
QJsonObject client;
client["clientName"] = QString("Client %1").arg(count); client["clientName"] = QString("Client %1").arg(count);
client["wireguardPublicKey"] = wireguardKey;
clientsTable[wireguardKey] = client;
count++; count++;
} }
clientsTable[client["wireguardPublicKey"].toString()] = client;
} }
// TODO error processing }
QByteArray newClientsTableString = QJsonDocument(clientsTable).toJson();
if (clientsTableString != newClientsTableString) {
error = uploadTextFileToContainer(container, credentials, newClientsTableString, clientsTableFile);
}
if (error != ErrorCode::NoError) {
return error;
}
clietns = clientsTable; clietns = clientsTable;
}
return error; return error;
} }
ErrorCode ServerController::setClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, QJsonObject &clietns) ErrorCode ServerController::setClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, QJsonObject &clietns)
{ {
ErrorCode error = ErrorCode::NoError; auto mainProtocolString = ProtocolProps::protoToString(mainProtocol);
if (mainProtocol == Proto::OpenVpn) { const QString clientsTableFile = QString("opt/amnezia/%1/clientsTable").arg(mainProtocolString);
error = uploadTextFileToContainer(container, credentials, QJsonDocument(clietns).toJson(), "opt/amnezia/openvpn/clientsTable"); ErrorCode error = uploadTextFileToContainer(container, credentials, QJsonDocument(clietns).toJson(), clientsTableFile);
} else if (mainProtocol == Proto::WireGuard) {
}
return error; return error;
} }

View file

@ -21,11 +21,15 @@ void ClientManagementModel::setContent(const QVector<QVariant> &data)
endResetModel(); endResetModel();
} }
QJsonObject ClientManagementModel::getContent() QJsonObject ClientManagementModel::getContent(Proto protocol)
{ {
QJsonObject clientsTable; QJsonObject clientsTable;
for (const auto &item : m_content) { for (const auto &item : m_content) {
if (protocol == Proto::OpenVpn) {
clientsTable[item.toJsonObject()["openvpnCertId"].toString()] = item.toJsonObject(); clientsTable[item.toJsonObject()["openvpnCertId"].toString()] = item.toJsonObject();
} else if (protocol == Proto::WireGuard) {
clientsTable[item.toJsonObject()["wireguardPublicKey"].toString()] = item.toJsonObject();
}
} }
return clientsTable; return clientsTable;
} }

View file

@ -21,7 +21,7 @@ public:
void clearData(); void clearData();
void setContent(const QVector<QVariant> &data); void setContent(const QVector<QVariant> &data);
QJsonObject getContent(); QJsonObject getContent(Proto protocol);
int rowCount(const QModelIndex &parent = QModelIndex()) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
void setData(const QModelIndex &index, QVariant data, int role = Qt::DisplayRole); void setData(const QModelIndex &index, QVariant data, int role = Qt::DisplayRole);

View file

@ -1,5 +1,9 @@
#include "ClientInfoLogic.h" #include "ClientInfoLogic.h"
#include <QMessageBox>
#include "defines.h"
#include "core/errorstrings.h"
#include "core/servercontroller.h" #include "core/servercontroller.h"
#include "ui/models/clientManagementModel.h" #include "ui/models/clientManagementModel.h"
#include "ui/uilogic.h" #include "ui/uilogic.h"
@ -44,15 +48,21 @@ void ClientInfoLogic::onLineEditNameAliasEditingFinished()
auto modelIndex = model->index(m_currentClientIndex); auto modelIndex = model->index(m_currentClientIndex);
model->setData(modelIndex, m_lineEditNameAliasText, ClientManagementModel::ClientRoles::NameRole); model->setData(modelIndex, m_lineEditNameAliasText, ClientManagementModel::ClientRoles::NameRole);
auto clientsTable = model->getContent();
DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex); DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex);
auto protocols = ContainerProps::protocolsForContainer(selectedContainer); auto protocols = ContainerProps::protocolsForContainer(selectedContainer);
if (!protocols.empty()) { if (!protocols.empty()) {
auto currentMainProtocol = protocols.front(); auto currentMainProtocol = protocols.front();
m_serverController->setClientsList(m_settings->serverCredentials(uiLogic()->selectedServerIndex), auto clientsTable = model->getContent(currentMainProtocol);
ErrorCode error = m_serverController->setClientsList(m_settings->serverCredentials(uiLogic()->selectedServerIndex),
selectedContainer, selectedContainer,
currentMainProtocol, currentMainProtocol,
clientsTable); clientsTable);
if (error != ErrorCode::NoError) {
QMessageBox::warning(nullptr, APPLICATION_NAME,
tr("An error occurred while getting the list of clients.") + "\n" + errorString(error));
return;
}
} }
} }

View file

@ -1,5 +1,9 @@
#include "ClientManagementLogic.h" #include "ClientManagementLogic.h"
#include <QMessageBox>
#include "defines.h"
#include "core/errorstrings.h"
#include "core/servercontroller.h" #include "core/servercontroller.h"
#include "ui/pages_logic/ClientInfoLogic.h" #include "ui/pages_logic/ClientInfoLogic.h"
#include "ui/models/clientManagementModel.h" #include "ui/models/clientManagementModel.h"
@ -24,8 +28,13 @@ void ClientManagementLogic::onUpdatePage()
if (!protocols.empty()) { if (!protocols.empty()) {
m_currentMainProtocol = protocols.front(); m_currentMainProtocol = protocols.front();
ErrorCode e = m_serverController->getClientsList(m_settings->serverCredentials(uiLogic()->selectedServerIndex), ErrorCode error = m_serverController->getClientsList(m_settings->serverCredentials(uiLogic()->selectedServerIndex),
selectedContainer, m_currentMainProtocol, clients); selectedContainer, m_currentMainProtocol, clients);
if (error != ErrorCode::NoError) {
QMessageBox::warning(nullptr, APPLICATION_NAME,
tr("An error occurred while getting the list of clients.") + "\n" + errorString(error));
return;
}
} }
QVector<QVariant> clientsArray; QVector<QVariant> clientsArray;
for (auto &clientId : clients.keys()) { for (auto &clientId : clients.keys()) {