mirror of
https://github.com/MatsuriDayo/nekoray.git
synced 2025-12-17 12:34:37 +03:00
Optimize permission for linux
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
9
res/public/linux_pkexec.sh
Normal file
9
res/public/linux_pkexec.sh
Normal 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 $@
|
||||
9
res/public/linux_pkexec_root.sh
Normal file
9
res/public/linux_pkexec_root.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
set -e
|
||||
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "[Warning] Not running as root"
|
||||
fi
|
||||
|
||||
#echo $$ >$PID_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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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]";
|
||||
|
||||
Reference in New Issue
Block a user