Merge pull request #189 from amnezia-vpn/feature/check-user-in-sudo

feature/check-user-in-sudo
This commit is contained in:
pokamest 2023-04-08 16:38:00 +01:00 committed by GitHub
commit de4245025c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 79 additions and 33 deletions

View file

@ -32,6 +32,7 @@ enum ErrorCode
ServerContainerMissingError,
ServerDockerFailedError,
ServerCancelInstallation,
ServerUserNotInSudo,
// Ssh connection errors
SshRequsetDeniedError, SshInterruptedError, SshInternalError,

View file

@ -16,6 +16,7 @@ QString errorString(ErrorCode code){
case(ServerContainerMissingError): return QObject::tr("Server error: Docker container missing");
case(ServerDockerFailedError): return QObject::tr("Server error: Docker failed");
case(ServerCancelInstallation): return QObject::tr("Installation canceled by user");
case(ServerUserNotInSudo): return QObject::tr("The user does not have permission to use sudo");
// Libssh errors
case(SshRequsetDeniedError): return QObject::tr("Ssh request was denied");

View file

@ -32,6 +32,7 @@ QString amnezia::scriptName(SharedScriptType type)
case SharedScriptType::setup_host_firewall: return QLatin1String("setup_host_firewall.sh");
case SharedScriptType::check_connection: return QLatin1String("check_connection.sh");
case SharedScriptType::check_server_is_busy: return QLatin1String("check_server_is_busy.sh");
case SharedScriptType::check_user_in_sudo: return QLatin1String("check_user_in_sudo.sh");
}
}

View file

@ -16,7 +16,8 @@ enum SharedScriptType {
remove_all_containers,
setup_host_firewall,
check_connection,
check_server_is_busy
check_server_is_busy,
check_user_in_sudo
};
enum ProtocolScriptType {
// Protocol scripts

View file

@ -245,11 +245,17 @@ ErrorCode ServerController::setupContainer(const ServerCredentials &credentials,
//qDebug().noquote() << QJsonDocument(config).toJson();
ErrorCode e = ErrorCode::NoError;
e = isUserInSudo(credentials, container);
if (e) return e;
if (!isUpdate) {
e = isServerPortBusy(credentials, container, config);
if (e) return e;
}
e = isServerDpkgBusy(credentials, container);
if (e) return e;
e = installDockerWorker(credentials, container);
if (e) return e;
qDebug().noquote() << "ServerController::setupContainer installDockerWorker finished";
@ -368,37 +374,6 @@ ErrorCode ServerController::installDockerWorker(const ServerCredentials &credent
return ErrorCode::NoError;
};
QFutureWatcher<ErrorCode> watcher;
QFuture<ErrorCode> future = QtConcurrent::run([this, &stdOut, &cbReadStdOut, &cbReadStdErr, &credentials]() {
do {
if (m_cancelInstallation) {
return ErrorCode::ServerCancelInstallation;
}
stdOut.clear();
runScript(credentials,
replaceVars(amnezia::scriptData(SharedScriptType::check_server_is_busy),
genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr);
if (!stdOut.isEmpty() || stdOut.contains("Unable to acquire the dpkg frontend lock")) {
emit serverIsBusy(true);
QThread::msleep(1000);
}
} while (!stdOut.isEmpty());
return ErrorCode::NoError;
});
QEventLoop wait;
QObject::connect(&watcher, &QFutureWatcher<ErrorCode>::finished, &wait, &QEventLoop::quit);
watcher.setFuture(future);
wait.exec();
m_cancelInstallation = false;
emit serverIsBusy(false);
if (future.result() != ErrorCode::NoError) {
return future.result();
}
ErrorCode error = runScript(credentials,
replaceVars(amnezia::scriptData(SharedScriptType::install_docker),
genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr);
@ -692,6 +667,68 @@ ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credential
return ErrorCode::NoError;
}
ErrorCode ServerController::isUserInSudo(const ServerCredentials &credentials, DockerContainer container)
{
QString stdOut;
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
stdOut += data + "\n";
return ErrorCode::NoError;
};
auto cbReadStdErr = [&](const QString &data, libssh::Client &) {
stdOut += data + "\n";
return ErrorCode::NoError;
};
const QString scriptData = amnezia::scriptData(SharedScriptType::check_user_in_sudo);
ErrorCode error = runScript(credentials, replaceVars(scriptData, genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr);
if (!stdOut.contains("sudo")) return ErrorCode::ServerUserNotInSudo;
return error;
}
ErrorCode ServerController::isServerDpkgBusy(const ServerCredentials &credentials, DockerContainer container)
{
QString stdOut;
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
stdOut += data + "\n";
return ErrorCode::NoError;
};
auto cbReadStdErr = [&](const QString &data, libssh::Client &) {
stdOut += data + "\n";
return ErrorCode::NoError;
};
QFutureWatcher<ErrorCode> watcher;
QFuture<ErrorCode> future = QtConcurrent::run([this, &stdOut, &cbReadStdOut, &cbReadStdErr, &credentials]() {
do {
if (m_cancelInstallation) {
return ErrorCode::ServerCancelInstallation;
}
stdOut.clear();
runScript(credentials,
replaceVars(amnezia::scriptData(SharedScriptType::check_server_is_busy),
genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr);
if (!stdOut.isEmpty() || stdOut.contains("Unable to acquire the dpkg frontend lock")) {
emit serverIsBusy(true);
QThread::msleep(1000);
}
} while (!stdOut.isEmpty());
return ErrorCode::NoError;
});
QEventLoop wait;
QObject::connect(&watcher, &QFutureWatcher<ErrorCode>::finished, &wait, &QEventLoop::quit);
watcher.setFuture(future);
wait.exec();
m_cancelInstallation = false;
emit serverIsBusy(false);
return future.result();
}
ErrorCode ServerController::getAlreadyInstalledContainers(const ServerCredentials &credentials, QMap<DockerContainer, QJsonObject> &installedContainers)
{
QString stdOut;

View file

@ -66,7 +66,9 @@ private:
ErrorCode isServerPortBusy(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config);
bool isReinstallContainerRequred(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig);
ErrorCode isUserInSudo(const ServerCredentials &credentials, DockerContainer container);
ErrorCode isServerDpkgBusy(const ServerCredentials &credentials, DockerContainer container);
ErrorCode uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data,
const QString &remotePath, libssh::SftpOverwriteMode overwriteMode = libssh::SftpOverwriteMode::SftpOverwriteExisting);

View file

@ -166,5 +166,6 @@
<file>ui/qml/Pages/PageAdvancedServerSettings.qml</file>
<file>ui/qml/Controls/PopupWarning.qml</file>
<file>ui/qml/Controls/PopupWithTextField.qml</file>
<file>server_scripts/check_user_in_sudo.sh</file>
</qresource>
</RCC>

View file

@ -0,0 +1,2 @@
CUR_USER=$(whoami);\
groups $CUR_USER