Refactoring

This commit is contained in:
pokamest 2021-01-06 17:12:24 +03:00
parent 13f9764853
commit 5eede71667
21 changed files with 566 additions and 220 deletions

View file

@ -6,19 +6,19 @@
#include <QPointer>
#include <QTimer>
//#include "sshclient.h"
//#include "sshprocess.h"
#include "sshconnectionmanager.h"
#include "sshremoteprocess.h"
using namespace QSsh;
bool ServerController::runScript(const SshConnectionParameters &sshParams, QString script)
ErrorCode ServerController::runScript(const SshConnectionParameters &sshParams, QString script)
{
QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false"));
SshConnection *client = connectToHost(sshParams);
if (client->state() != SshConnection::State::Connected) {
return fromSshConnectionErrorCode(client->errorState());
}
script.replace("\r", "");
@ -36,49 +36,52 @@ bool ServerController::runScript(const SshConnectionParameters &sshParams, QStri
if (!proc) {
qCritical() << "Failed to create SshRemoteProcess, breaking.";
return false;
return ErrorCode::SshRemoteProcessCreationError;
}
QEventLoop wait;
int exitStatus;
QObject::connect(proc.data(), &SshRemoteProcess::started, &wait, [](){
qDebug() << "Command started";
});
// QObject::connect(proc.data(), &SshRemoteProcess::started, &wait, [](){
// qDebug() << "Command started";
// });
QObject::connect(proc.data(), &SshRemoteProcess::closed, &wait, [&](int status){
qDebug() << "Remote process exited with status" << status;
exitStatus = status;
//qDebug() << "Remote process exited with status" << status;
wait.quit();
});
QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, [proc](){
QString s = proc->readAllStandardOutput();
if (s != "." && !s.isEmpty()) {
qDebug().noquote() << s;
}
});
// QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, [proc](){
// QString s = proc->readAllStandardOutput();
// if (s != "." && !s.isEmpty()) {
// qDebug().noquote() << s << s.size();
// }
// });
QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, [proc](){
QString s = proc->readAllStandardError();
if (s != "." && !s.isEmpty()) {
qDebug().noquote() << s;
}
});
// QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, [proc](){
// QString s = proc->readAllStandardError();
// if (s != "." && !s.isEmpty()) {
// qDebug().noquote() << s;
// }
// });
proc->start();
if (i < lines.count() - 1) {
wait.exec();
}
if (SshRemoteProcess::ExitStatus(exitStatus) != QSsh::SshRemoteProcess::ExitStatus::NormalExit) {
return fromSshProcessExitStatus(exitStatus);
}
}
qDebug() << "ServerController::runScript finished\n";
// client->disconnectFromHost();
// client->deleteLater();
return true;
return ErrorCode::NoError;
}
void ServerController::uploadTextFileToContainer(const SshConnectionParameters &sshParams,
ErrorCode ServerController::uploadTextFileToContainer(const ServerCredentials &credentials,
QString &file, const QString &path)
{
QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false"));
@ -88,60 +91,85 @@ void ServerController::uploadTextFileToContainer(const SshConnectionParameters &
qDebug().noquote() << script;
SshConnection *client = connectToHost(sshParams);
SshConnection *client = connectToHost(sshParams(credentials));
if (client->state() != SshConnection::State::Connected) {
return fromSshConnectionErrorCode(client->errorState());
}
QSharedPointer<SshRemoteProcess> proc = client->createRemoteProcess(script.toUtf8());
if (!proc) {
qCritical() << "Failed to create SshRemoteProcess, breaking.";
return;
return ErrorCode::SshRemoteProcessCreationError;
}
QEventLoop wait;
int exitStatus = 0;
QObject::connect(proc.data(), &SshRemoteProcess::started, &wait, [](){
qDebug() << "Command started";
});
// QObject::connect(proc.data(), &SshRemoteProcess::started, &wait, [](){
// qDebug() << "Command started";
// });
QObject::connect(proc.data(), &SshRemoteProcess::closed, &wait, [&](int status){
qDebug() << "Remote process exited with status" << status;
//qDebug() << "Remote process exited with status" << status;
exitStatus = status;
wait.quit();
});
QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, [proc](){
qDebug().noquote() << proc->readAllStandardOutput();
});
// QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, [proc](){
// qDebug().noquote() << proc->readAllStandardOutput();
// });
QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, [proc](){
qDebug().noquote() << proc->readAllStandardError();
});
// QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, [proc](){
// qDebug().noquote() << proc->readAllStandardError();
// });
proc->start();
wait.exec();
return fromSshProcessExitStatus(exitStatus);
}
QString ServerController::getTextFileFromContainer(const SshConnectionParameters &sshParams, const QString &path)
QString ServerController::getTextFileFromContainer(const ServerCredentials &credentials, const QString &path,
ErrorCode *errorCode)
{
QString script = QString("docker exec -i amneziavpn sh -c \"cat \'%1\'\"").
arg(path);
qDebug().noquote() << "Copy file from container\n" << script;
SshConnection *client = connectToHost(sshParams);
SshConnection *client = connectToHost(sshParams(credentials));
if (client->state() != SshConnection::State::Connected) {
if (errorCode) *errorCode = fromSshConnectionErrorCode(client->errorState());
return QString();
}
QSharedPointer<SshRemoteProcess> proc = client->createRemoteProcess(script.toUtf8());
if (!proc) {
qCritical() << "Failed to create SshRemoteProcess, breaking.";
if (errorCode) *errorCode = ErrorCode::SshRemoteProcessCreationError;
return QString();
}
QEventLoop wait;
int exitStatus = 0;
QObject::connect(proc.data(), &SshRemoteProcess::closed, &wait, [&](int ){
QObject::connect(proc.data(), &SshRemoteProcess::closed, &wait, [&](int status){
exitStatus = status;
wait.quit();
});
proc->start();
wait.exec();
if (SshRemoteProcess::ExitStatus(exitStatus) != QSsh::SshRemoteProcess::ExitStatus::NormalExit) {
if (errorCode) *errorCode = fromSshProcessExitStatus(exitStatus);
}
return proc->readAllStandardOutput();
}
bool ServerController::signCert(const SshConnectionParameters &sshParams, QString clientId)
ErrorCode ServerController::signCert(const ServerCredentials &credentials, QString clientId)
{
QString script_import = QString("docker exec -i amneziavpn bash -c \"cd /opt/amneziavpn_data && "
"easyrsa import-req /opt/amneziavpn_data/clients/%1.req %1 &>/dev/null\"")
@ -153,55 +181,121 @@ bool ServerController::signCert(const SshConnectionParameters &sshParams, QStrin
QStringList script {script_import, script_sign};
return runScript(sshParams, script.join("\n"));
return runScript(sshParams(credentials), script.join("\n"));
}
bool ServerController::removeServer(const SshConnectionParameters &sshParams, ServerController::ServerType sType)
ErrorCode ServerController::checkOpenVpnServer(const ServerCredentials &credentials)
{
QString caCert = ServerController::getTextFileFromContainer(credentials, ServerController::caCertPath());
QString taKey = ServerController::getTextFileFromContainer(credentials, ServerController::taKeyPath());
if (!caCert.isEmpty() && !taKey.isEmpty()) {
return ErrorCode::NoError;
}
else {
return ErrorCode::ServerCheckFailed;
}
}
ErrorCode ServerController::fromSshConnectionErrorCode(SshError error)
{
switch (error) {
case(SshNoError): return ErrorCode::NoError;
case(QSsh::SshSocketError): return ErrorCode::SshSocketError;
case(QSsh::SshTimeoutError): return ErrorCode::SshTimeoutError;
case(QSsh::SshProtocolError): return ErrorCode::SshProtocolError;
case(QSsh::SshHostKeyError): return ErrorCode::SshHostKeyError;
case(QSsh::SshKeyFileError): return ErrorCode::SshKeyFileError;
case(QSsh::SshAuthenticationError): return ErrorCode::SshAuthenticationError;
case(QSsh::SshClosedByServerError): return ErrorCode::SshClosedByServerError;
case(QSsh::SshInternalError): return ErrorCode::SshInternalError;
}
}
ErrorCode ServerController::fromSshProcessExitStatus(int exitStatus)
{
switch (SshRemoteProcess::ExitStatus(exitStatus)) {
case(SshRemoteProcess::ExitStatus::NormalExit): return ErrorCode::NoError;
case(SshRemoteProcess::ExitStatus::FailedToStart): return ErrorCode::FailedToStartRemoteProcessError;
case(SshRemoteProcess::ExitStatus::CrashExit): return ErrorCode::RemoteProcessCrashError;
}
}
SshConnectionParameters ServerController::sshParams(const ServerCredentials &credentials)
{
QSsh::SshConnectionParameters sshParams;
sshParams.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypePassword;
sshParams.host = credentials.hostName;
sshParams.userName = credentials.userName;
sshParams.password = credentials.password;
sshParams.timeout = 10;
sshParams.port = credentials.port;
sshParams.hostKeyCheckingMode = QSsh::SshHostKeyCheckingMode::SshHostKeyCheckingNone;
return sshParams;
}
ErrorCode ServerController::removeServer(const ServerCredentials &credentials, Protocol proto)
{
QString scriptFileName;
if (sType == OpenVPN) {
if (proto == Protocol::OpenVpn) {
scriptFileName = ":/server_scripts/remove_openvpn_server.sh";
}
QString scriptData;
QFile file(scriptFileName);
if (! file.open(QIODevice::ReadOnly)) {
return false;
}
if (! file.open(QIODevice::ReadOnly)) return ErrorCode::InternalError;
scriptData = file.readAll();
if (scriptData.isEmpty()) return false;
if (scriptData.isEmpty()) return ErrorCode::InternalError;
return runScript(sshParams, scriptData);
return runScript(sshParams(credentials), scriptData);
}
bool ServerController::setupServer(const SshConnectionParameters &sshParams, ServerController::ServerType sType)
ErrorCode ServerController::setupServer(const ServerCredentials &credentials, Protocol proto)
{
QString scriptFileName;
if (sType == OpenVPN) {
scriptFileName = ":/server_scripts/setup_openvpn_server.sh";
if (proto == Protocol::OpenVpn) {
return setupOpenVpnServer(credentials);
}
else if (proto == Protocol::ShadowSocks) {
return setupShadowSocksServer(credentials);
}
else if (proto == Protocol::Any) {
// TODO: run concurently
return setupOpenVpnServer(credentials);
//setupShadowSocksServer(credentials);
}
return ErrorCode::NotImplementedError;
}
ErrorCode ServerController::setupOpenVpnServer(const ServerCredentials &credentials)
{
QString scriptData;
QString scriptFileName = ":/server_scripts/setup_openvpn_server.sh";
QFile file(scriptFileName);
if (! file.open(QIODevice::ReadOnly)) {
return false;
}
if (! file.open(QIODevice::ReadOnly)) return ErrorCode::InternalError;
scriptData = file.readAll();
if (scriptData.isEmpty()) return false;
if (scriptData.isEmpty()) return ErrorCode::InternalError;
return runScript(sshParams, scriptData);
ErrorCode e = runScript(sshParams(credentials), scriptData);
if (e) return e;
//return ok;
return checkOpenVpnServer(credentials);
}
ErrorCode ServerController::setupShadowSocksServer(const ServerCredentials &credentials)
{
return ErrorCode::NotImplementedError;
}
SshConnection *ServerController::connectToHost(const SshConnectionParameters &sshParams)
{
SshConnection *client = acquireConnection(sshParams);
//QPointer<SshConnection> client = new SshConnection(serverInfo);
QEventLoop waitssh;
QObject::connect(client, &SshConnection::connected, &waitssh, [&]() {