Optimize permission for linux

This commit is contained in:
arm64v8a
2023-05-02 11:58:33 +09:00
parent 50387db15e
commit 3d2ce33a75
10 changed files with 73 additions and 11 deletions

View File

@@ -9,6 +9,12 @@
#include <QJsonArray>
#include <QJsonDocument>
#ifdef Q_OS_WIN
#include "sys/windows/guihelper.h"
#else
#include <unistd.h>
#endif
namespace NekoRay {
DataStore *dataStore = new DataStore();
@@ -371,4 +377,20 @@ namespace NekoRay {
return {};
}
short isAdminCache = -1;
bool isAdmin() {
if (isAdminCache >= 0) return isAdminCache;
auto admin = NekoRay::dataStore->flag_linux_run_core_as_admin;
#ifdef Q_OS_WIN
admin = Windows_IsInAdmin();
#else
admin |= geteuid() == 0;
#endif
isAdminCache = admin;
return admin;
};
} // namespace NekoRay

View File

@@ -11,6 +11,9 @@ namespace NekoRay {
inline int coreType = NekoRay::CoreType::V2RAY;
QString FindCoreAsset(const QString &name);
bool isAdmin();
} // namespace NekoRay
#define IS_NEKO_BOX (NekoRay::coreType == NekoRay::CoreType::SING_BOX)

View File

@@ -71,6 +71,7 @@ namespace NekoRay {
bool flag_many = false;
bool flag_tray = false;
bool flag_debug = false;
bool flag_linux_run_core_as_admin = false;
// Saved

View File

@@ -81,6 +81,7 @@ int main(int argc, char* argv[]) {
if (NekoRay::dataStore->argv.contains("-appdata")) NekoRay::dataStore->flag_use_appdata = true;
if (NekoRay::dataStore->argv.contains("-tray")) NekoRay::dataStore->flag_tray = true;
if (NekoRay::dataStore->argv.contains("-debug")) NekoRay::dataStore->flag_debug = true;
if (NekoRay::dataStore->argv.contains("-flag_linux_run_core_as_admin")) NekoRay::dataStore->flag_linux_run_core_as_admin = true;
#ifdef NKR_CPP_USE_APPDATA
NekoRay::dataStore->flag_use_appdata = true; // Example: Package & MacOS
#endif

View File

@@ -0,0 +1,9 @@
set -e
command -v pkexec >/dev/null 2>&1 || echo "[Warning] pkexec not found"
command -v pkill >/dev/null 2>&1 || echo "[Warning] pkill not found"
BASEDIR="$(dirname -- "$(readlink -f -- "$0")")"
pkexec --keep-cwd \
bash "$BASEDIR"/linux_pkexec_root.sh $@

View File

@@ -0,0 +1,9 @@
set -e
if [ "$EUID" -ne 0 ]; then
echo "[Warning] Not running as root"
fi
#echo $$ >$PID_FILE
$@

View File

@@ -11,7 +11,7 @@ if [ "$(uname)" == "Darwin" ]; then
fi
[ -z $TABLE_FWMARK ] && echo "Please set env TABLE_FWMARK" && exit
command -v pkill >/dev/null 2>&1 || exit
command -v pkill >/dev/null 2>&1 || echo "[Warning] pkill not found"
BASEDIR=$(dirname "$0")
cd $BASEDIR

View File

@@ -19,7 +19,7 @@ namespace NekoRay::sys {
if (started) return;
started = true;
if (show_log) {
if (managed) {
connect(this, &QProcess::readyReadStandardOutput, this, [&]() {
MW_show_log_ext_vt100(readAllStandardOutput().trimmed());
});
@@ -30,7 +30,7 @@ namespace NekoRay::sys {
if (!killed) {
crashed = true;
MW_show_log_ext(tag, "errorOccurred:" + errorString());
if (managed) MW_dialog_message("ExternalProcess", "Crashed");
MW_dialog_message("ExternalProcess", "Crashed");
}
});
connect(this, &QProcess::stateChanged, this, [&](QProcess::ProcessState state) {
@@ -41,15 +41,26 @@ namespace NekoRay::sys {
crashed = true;
MW_show_log_ext(tag, "[Error] Program exited accidentally: " + errorString());
Kill();
if (managed) MW_dialog_message("ExternalProcess", "Crashed");
MW_dialog_message("ExternalProcess", "Crashed");
}
}
});
MW_show_log_ext(tag, "[Starting] " + env.join(" ") + " " + program + " " + arguments.join(" "));
}
QProcess::setEnvironment(env);
if (NekoRay::dataStore->flag_linux_run_core_as_admin && dynamic_cast<CoreProcess *>(this)) {
arguments.prepend(program);
arguments.prepend(QApplication::applicationDirPath() + "/linux_pkexec.sh");
program = "bash";
}
QProcess::setEnvironment(env);
QProcess::start(program, arguments);
// waitForStarted();
// pid = processId();
}
void ExternalProcess::Kill() {
@@ -64,7 +75,6 @@ namespace NekoRay::sys {
CoreProcess::CoreProcess(const QString &core_path, const QStringList &args) : ExternalProcess() {
ExternalProcess::managed = false;
ExternalProcess::show_log = false;
ExternalProcess::program = core_path;
ExternalProcess::arguments = args;

View File

@@ -9,9 +9,9 @@ namespace NekoRay::sys {
QString program;
QStringList arguments;
QStringList env;
qint64 pid = 0;
bool managed = true; // MW_dialog_message
bool show_log = true;
ExternalProcess();
~ExternalProcess();

View File

@@ -640,6 +640,7 @@ void MainWindow::on_menu_exit_triggered() {
QProcess::startDetached("./updater", QStringList{});
} else if (exit_reason == 2 || exit_reason == 3) {
QDir::setCurrent(QApplication::applicationDirPath());
auto arguments = NekoRay::dataStore->argv;
if (arguments.length() > 0) arguments.removeFirst();
auto isLauncher = qEnvironmentVariable("NKR_FROM_LAUNCHER") == "1";
@@ -649,6 +650,9 @@ void MainWindow::on_menu_exit_triggered() {
if (exit_reason == 3) { // restart as admin
#ifdef Q_OS_WIN
WinCommander::runProcessElevated(program, arguments, "", WinCommander::SW_NORMAL, false);
#else
arguments << "-flag_linux_run_core_as_admin";
QProcess::startDetached(program, arguments);
#endif
} else {
QProcess::startDetached(program, arguments);
@@ -701,8 +705,15 @@ void MainWindow::neko_set_spmode_vpn(bool enable, bool save) {
if (enable != NekoRay::dataStore->spmode_vpn) {
if (enable) {
if (IS_NEKO_BOX_INTERNAL_TUN) {
bool requestPermission = false;
#ifdef Q_OS_WIN
if (!Windows_IsInAdmin()) {
requestPermission = true;
}
#else
requestPermission = !NekoRay::isAdmin();
#endif
if (requestPermission) {
auto n = QMessageBox::warning(GetMessageBoxParent(), software_name, tr("Please run NekoBox as admin"), QMessageBox::Yes | QMessageBox::No);
if (n == QMessageBox::Yes) {
this->exit_reason = 3;
@@ -710,8 +721,6 @@ void MainWindow::neko_set_spmode_vpn(bool enable, bool save) {
}
neko_set_spmode_FAILED
}
#endif
// TODO check permission for Linux
} else {
if (NekoRay::dataStore->need_keep_vpn_off) {
MessageBoxWarning(software_name, tr("Current server is incompatible with VPN. Please stop the server first, enable VPN mode, and then restart."));
@@ -781,9 +790,7 @@ void MainWindow::refresh_status(const QString &traffic_update) {
auto make_title = [=](bool isTray) {
QStringList tt;
#ifdef Q_OS_WIN
if (!isTray && Windows_IsInAdmin()) tt << "[Admin]";
#endif
if (!isTray && NekoRay::isAdmin()) tt << "[Admin]";
if (select_mode) tt << "[" + tr("Select") + "]";
if (!title_error.isEmpty()) tt << "[" + title_error + "]";
if (NekoRay::dataStore->spmode_vpn) tt << "[VPN]";