diff --git a/client/configurators/wireguard_configurator.cpp b/client/configurators/wireguard_configurator.cpp index 532d89f6..78f44afd 100644 --- a/client/configurators/wireguard_configurator.cpp +++ b/client/configurators/wireguard_configurator.cpp @@ -76,7 +76,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon { QString script = QString("cat %1 | grep AllowedIPs").arg(amnezia::protocols::wireguard::serverConfigPath); QString stdOut; - auto cbReadStdOut = [&](const QString &data, QSharedPointer proc) { + auto cbReadStdOut = [&](const QString &data) { stdOut += data + "\n"; }; diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index ae9ae74a..5193e5ee 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -93,8 +93,8 @@ ErrorCode ServerController::connectToHost(const ServerCredentials &credentials, ErrorCode ServerController::runScript(const ServerCredentials &credentials, QString script, - const std::function)> &cbReadStdOut, - const std::function)> &cbReadStdErr) { + const std::function &cbReadStdOut, + const std::function &cbReadStdErr) { std::shared_ptr session = m_sshClient.getSession(); if (!session) { @@ -137,7 +137,7 @@ ErrorCode ServerController::runScript(const ServerCredentials &credentials, QStr qDebug().noquote() << "EXEC" << lineToExec; Debug::appendSshLog("Run command:" + lineToExec); - error = session->writeToChannel(lineToExec); + error = session->writeToChannel(lineToExec, cbReadStdOut, cbReadStdErr); if (error != ErrorCode::NoError) { return error; } @@ -150,8 +150,8 @@ ErrorCode ServerController::runScript(const ServerCredentials &credentials, QStr ErrorCode ServerController::runContainerScript(const ServerCredentials &credentials, DockerContainer container, QString script, - const std::function)> &cbReadStdOut, - const std::function)> &cbReadStdErr) + const std::function &cbReadStdOut, + const std::function &cbReadStdErr) { QString fileName = "/opt/amnezia/" + Utils::getRandomString(16) + ".sh"; Debug::appendSshLog("Run container script for " + ContainerProps::containerToString(container) + QStringLiteral(":\n") + script); @@ -183,7 +183,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container, if (e) return e; QString stdOut; - auto cbReadStd = [&](const QString &data, QSharedPointer ) { + auto cbReadStd = [&](const QString &data) { stdOut += data + "\n"; }; @@ -245,7 +245,7 @@ QByteArray ServerController::getTextFileFromContainer(DockerContainer container, QString stdOut; - auto cbReadStdOut = [&](const QString &data, QSharedPointer proc) { + auto cbReadStdOut = [&](const QString &data) { stdOut += data; }; @@ -596,14 +596,14 @@ bool ServerController::isReinstallContainerRequred(DockerContainer container, co ErrorCode ServerController::installDockerWorker(const ServerCredentials &credentials, DockerContainer container) { QString stdOut; - auto cbReadStdOut = [&](const QString &data, QSharedPointer proc) { + auto cbReadStdOut = [&](const QString &data) { stdOut += data + "\n"; // if (data.contains("Automatically restart Docker daemon?")) { // proc->write("yes\n"); // } }; - auto cbReadStdErr = [&](const QString &data, QSharedPointer ) { + auto cbReadStdErr = [&](const QString &data) { stdOut += data + "\n"; }; @@ -633,7 +633,7 @@ ErrorCode ServerController::buildContainerWorker(const ServerCredentials &creden if (e) return e; QString stdOut; - auto cbReadStdOut = [&](const QString &data, QSharedPointer proc) { + auto cbReadStdOut = [&](const QString &data) { stdOut += data + "\n"; }; // auto cbReadStdErr = [&](const QString &data, QSharedPointer proc) { @@ -651,7 +651,7 @@ ErrorCode ServerController::buildContainerWorker(const ServerCredentials &creden ErrorCode ServerController::runContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config) { QString stdOut; - auto cbReadStdOut = [&](const QString &data, QSharedPointer proc) { + auto cbReadStdOut = [&](const QString &data) { stdOut += data + "\n"; }; // auto cbReadStdErr = [&](const QString &data, QSharedPointer proc) { @@ -677,10 +677,10 @@ ErrorCode ServerController::runContainerWorker(const ServerCredentials &credenti ErrorCode ServerController::configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config) { QString stdOut; - auto cbReadStdOut = [&](const QString &data, QSharedPointer proc) { + auto cbReadStdOut = [&](const QString &data) { stdOut += data + "\n"; }; - auto cbReadStdErr = [&](const QString &data, QSharedPointer proc) { + auto cbReadStdErr = [&](const QString &data) { stdOut += data + "\n"; }; @@ -813,10 +813,10 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential QString ServerController::checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode) { QString stdOut; - auto cbReadStdOut = [&](const QString &data, QSharedPointer proc) { + auto cbReadStdOut = [&](const QString &data) { stdOut += data + "\n"; }; - auto cbReadStdErr = [&](const QString &data, QSharedPointer ) { + auto cbReadStdErr = [&](const QString &data) { stdOut += data + "\n"; }; diff --git a/client/core/servercontroller.h b/client/core/servercontroller.h index 43d5789f..d1926a5a 100644 --- a/client/core/servercontroller.h +++ b/client/core/servercontroller.h @@ -67,12 +67,12 @@ public: QString replaceVars(const QString &script, const Vars &vars); ErrorCode runScript(const ServerCredentials &credentials, QString script, - const std::function)> &cbReadStdOut = nullptr, - const std::function)> &cbReadStdErr = nullptr); + const std::function &cbReadStdOut = nullptr, + const std::function &cbReadStdErr = nullptr); ErrorCode runContainerScript(const ServerCredentials &credentials, DockerContainer container, QString script, - const std::function)> &cbReadStdOut = nullptr, - const std::function)> &cbReadStdErr = nullptr); + const std::function &cbReadStdOut = nullptr, + const std::function &cbReadStdErr = nullptr); Vars genVarsForScript(const ServerCredentials &credentials, DockerContainer container = DockerContainer::None, const QJsonObject &config = QJsonObject()); diff --git a/client/core/sshsession.cpp b/client/core/sshsession.cpp index 9c779cdf..a41e2441 100644 --- a/client/core/sshsession.cpp +++ b/client/core/sshsession.cpp @@ -86,6 +86,7 @@ ErrorCode SshSession::initChannel(const ServerCredentials &credentials) if (result == SSH_OK && ssh_channel_is_open(m_channel)) { qDebug() << "SSH chanel opened"; + m_isChannelOpened = true; } else { qDebug() << ssh_get_error(m_session); return ErrorCode::SshAuthenticationError; @@ -103,22 +104,80 @@ ErrorCode SshSession::initChannel(const ServerCredentials &credentials) return ErrorCode::SshInternalError; } - result = ssh_channel_request_shell(m_channel); - if (result != SSH_OK) { - qDebug() << ssh_get_error(m_session); - return ErrorCode::SshInternalError; - } +// result = ssh_channel_request_shell(m_channel); +// if (result != SSH_OK) { +// qDebug() << ssh_get_error(m_session); +// return ErrorCode::SshInternalError; +// } return ErrorCode::NoError; } -ErrorCode SshSession::writeToChannel(const QString &data) +ErrorCode SshSession::writeToChannel(const QString &data, + const std::function &cbReadStdOut, + const std::function &cbReadStdErr) { QFutureWatcher watcher; connect(&watcher, &QFutureWatcher::finished, this, &SshSession::writeToChannelFinished); - QFuture future = QtConcurrent::run([this, &data]() { - return write(data); + QFuture future = QtConcurrent::run([this, &data, &cbReadStdOut, &cbReadStdErr]() { + const int channelReadTimeoutMs = 10; + const size_t bufferSize = 2048; + + int bytesRead = 0; + int attempts = 0; + char buffer[bufferSize]; + + std::string output1; + if (ssh_channel_is_open(m_channel) && !ssh_channel_is_eof(m_channel)) { + bytesRead = ssh_channel_read_timeout(m_channel, buffer, sizeof(buffer), 0, channelReadTimeoutMs); + while (bytesRead > 0) + { + output1.append(buffer, bytesRead); + bytesRead = ssh_channel_read_timeout(m_channel, buffer, sizeof(buffer), 0, channelReadTimeoutMs); + } + } + qDebug().noquote() << "stdOut: " << QString(output1.c_str()); + + int bytesWritten = ssh_channel_write(m_channel, data.toUtf8(), (uint32_t)data.size()); + if (bytesWritten == data.size()) { + std::string stdOut; + std::string stdErr; + + auto readOutput = [&](bool isStdErr) { + std::string output; + if (ssh_channel_is_open(m_channel) && !ssh_channel_is_eof(m_channel)) { + bytesRead = ssh_channel_read_timeout(m_channel, buffer, sizeof(buffer), isStdErr, channelReadTimeoutMs); + while (bytesRead > 0) + { + output.append(buffer, bytesRead); + bytesRead = ssh_channel_read_timeout(m_channel, buffer, sizeof(buffer), isStdErr, channelReadTimeoutMs); + } + } + return output; + }; + + stdOut = readOutput(false); + stdErr = readOutput(true); + + if (cbReadStdOut){ + cbReadStdOut(stdOut.c_str()); + } + if (cbReadStdErr){ + cbReadStdErr(stdErr.c_str()); + } + if (!stdOut.empty()) { + qDebug().noquote() << "stdOut: " << QString(stdOut.c_str()); + } + if (!stdErr.empty()) { + qDebug().noquote() << "stdErr: " << QString(stdOut.c_str()); + } + } else { + qDebug() << ssh_get_error(m_session); + return ErrorCode::SshInternalError; + } + m_isNeedSendChannelEof = true; + return ErrorCode::NoError; }); watcher.setFuture(future); @@ -129,39 +188,3 @@ ErrorCode SshSession::writeToChannel(const QString &data) return watcher.result(); } - -ErrorCode SshSession::write(const QString &data) -{ - const int channelReadTimeoutMs = 10; - const size_t bufferSize = 2048; - - int bytesToRead = 0; - int attempts = 0; - char buffer[bufferSize]; - - int bytesWritten = ssh_channel_write(m_channel, data.toUtf8(), (uint32_t)data.size()); - if (bytesWritten == data.size()) { - while (bytesToRead != 0 || attempts < 100){ - if (ssh_channel_is_open(m_channel) && !ssh_channel_is_eof(m_channel)) { - bytesToRead = ssh_channel_read_timeout(m_channel, buffer, sizeof(buffer), 0, channelReadTimeoutMs); - if (bytesToRead > 0) { - attempts = 0; - std::string strbuf(buffer, bytesToRead); -// QByteArray qbuff(buffer, bytesToRead); -// QString outp(buffer); - -// if (cbReadStdOut){ -// cbReadStdOut(outp, nullptr); -// } - qDebug().noquote() << QString(strbuf.c_str()); - } else { - attempts++; - } - } - } - } else { - qDebug() << ssh_get_error(m_session); - return ErrorCode::SshInternalError; - } - return ErrorCode::NoError; -} diff --git a/client/core/sshsession.h b/client/core/sshsession.h index 419b90ef..5a399214 100644 --- a/client/core/sshsession.h +++ b/client/core/sshsession.h @@ -18,10 +18,11 @@ public: ~SshSession(); ErrorCode initChannel(const ServerCredentials &credentials); - ErrorCode writeToChannel(const QString &data); + ErrorCode writeToChannel(const QString &data, + const std::function &cbReadStdOut, + const std::function &cbReadStdErr); private: ErrorCode connectToHost(const ServerCredentials &credentials); - ErrorCode write(const QString &data); ssh_session m_session; ssh_channel m_channel;