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 <QJsonArray>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include "sys/windows/guihelper.h"
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace NekoRay {
|
namespace NekoRay {
|
||||||
|
|
||||||
DataStore *dataStore = new DataStore();
|
DataStore *dataStore = new DataStore();
|
||||||
@@ -371,4 +377,20 @@ namespace NekoRay {
|
|||||||
return {};
|
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
|
} // namespace NekoRay
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ namespace NekoRay {
|
|||||||
inline int coreType = NekoRay::CoreType::V2RAY;
|
inline int coreType = NekoRay::CoreType::V2RAY;
|
||||||
|
|
||||||
QString FindCoreAsset(const QString &name);
|
QString FindCoreAsset(const QString &name);
|
||||||
|
|
||||||
|
bool isAdmin();
|
||||||
|
|
||||||
} // namespace NekoRay
|
} // namespace NekoRay
|
||||||
|
|
||||||
#define IS_NEKO_BOX (NekoRay::coreType == NekoRay::CoreType::SING_BOX)
|
#define IS_NEKO_BOX (NekoRay::coreType == NekoRay::CoreType::SING_BOX)
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ namespace NekoRay {
|
|||||||
bool flag_many = false;
|
bool flag_many = false;
|
||||||
bool flag_tray = false;
|
bool flag_tray = false;
|
||||||
bool flag_debug = false;
|
bool flag_debug = false;
|
||||||
|
bool flag_linux_run_core_as_admin = false;
|
||||||
|
|
||||||
// Saved
|
// 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("-appdata")) NekoRay::dataStore->flag_use_appdata = true;
|
||||||
if (NekoRay::dataStore->argv.contains("-tray")) NekoRay::dataStore->flag_tray = 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("-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
|
#ifdef NKR_CPP_USE_APPDATA
|
||||||
NekoRay::dataStore->flag_use_appdata = true; // Example: Package & MacOS
|
NekoRay::dataStore->flag_use_appdata = true; // Example: Package & MacOS
|
||||||
#endif
|
#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
|
fi
|
||||||
|
|
||||||
[ -z $TABLE_FWMARK ] && echo "Please set env TABLE_FWMARK" && exit
|
[ -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")
|
BASEDIR=$(dirname "$0")
|
||||||
cd $BASEDIR
|
cd $BASEDIR
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace NekoRay::sys {
|
|||||||
if (started) return;
|
if (started) return;
|
||||||
started = true;
|
started = true;
|
||||||
|
|
||||||
if (show_log) {
|
if (managed) {
|
||||||
connect(this, &QProcess::readyReadStandardOutput, this, [&]() {
|
connect(this, &QProcess::readyReadStandardOutput, this, [&]() {
|
||||||
MW_show_log_ext_vt100(readAllStandardOutput().trimmed());
|
MW_show_log_ext_vt100(readAllStandardOutput().trimmed());
|
||||||
});
|
});
|
||||||
@@ -30,7 +30,7 @@ namespace NekoRay::sys {
|
|||||||
if (!killed) {
|
if (!killed) {
|
||||||
crashed = true;
|
crashed = true;
|
||||||
MW_show_log_ext(tag, "errorOccurred:" + errorString());
|
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) {
|
connect(this, &QProcess::stateChanged, this, [&](QProcess::ProcessState state) {
|
||||||
@@ -41,15 +41,26 @@ namespace NekoRay::sys {
|
|||||||
crashed = true;
|
crashed = true;
|
||||||
MW_show_log_ext(tag, "[Error] Program exited accidentally: " + errorString());
|
MW_show_log_ext(tag, "[Error] Program exited accidentally: " + errorString());
|
||||||
Kill();
|
Kill();
|
||||||
if (managed) MW_dialog_message("ExternalProcess", "Crashed");
|
MW_dialog_message("ExternalProcess", "Crashed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
MW_show_log_ext(tag, "[Starting] " + env.join(" ") + " " + program + " " + arguments.join(" "));
|
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::setEnvironment(env);
|
||||||
QProcess::start(program, arguments);
|
QProcess::start(program, arguments);
|
||||||
|
|
||||||
|
// waitForStarted();
|
||||||
|
// pid = processId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExternalProcess::Kill() {
|
void ExternalProcess::Kill() {
|
||||||
@@ -64,7 +75,6 @@ namespace NekoRay::sys {
|
|||||||
|
|
||||||
CoreProcess::CoreProcess(const QString &core_path, const QStringList &args) : ExternalProcess() {
|
CoreProcess::CoreProcess(const QString &core_path, const QStringList &args) : ExternalProcess() {
|
||||||
ExternalProcess::managed = false;
|
ExternalProcess::managed = false;
|
||||||
ExternalProcess::show_log = false;
|
|
||||||
ExternalProcess::program = core_path;
|
ExternalProcess::program = core_path;
|
||||||
ExternalProcess::arguments = args;
|
ExternalProcess::arguments = args;
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ namespace NekoRay::sys {
|
|||||||
QString program;
|
QString program;
|
||||||
QStringList arguments;
|
QStringList arguments;
|
||||||
QStringList env;
|
QStringList env;
|
||||||
|
qint64 pid = 0;
|
||||||
|
|
||||||
bool managed = true; // MW_dialog_message
|
bool managed = true; // MW_dialog_message
|
||||||
bool show_log = true;
|
|
||||||
|
|
||||||
ExternalProcess();
|
ExternalProcess();
|
||||||
~ExternalProcess();
|
~ExternalProcess();
|
||||||
|
|||||||
@@ -640,6 +640,7 @@ void MainWindow::on_menu_exit_triggered() {
|
|||||||
QProcess::startDetached("./updater", QStringList{});
|
QProcess::startDetached("./updater", QStringList{});
|
||||||
} else if (exit_reason == 2 || exit_reason == 3) {
|
} else if (exit_reason == 2 || exit_reason == 3) {
|
||||||
QDir::setCurrent(QApplication::applicationDirPath());
|
QDir::setCurrent(QApplication::applicationDirPath());
|
||||||
|
|
||||||
auto arguments = NekoRay::dataStore->argv;
|
auto arguments = NekoRay::dataStore->argv;
|
||||||
if (arguments.length() > 0) arguments.removeFirst();
|
if (arguments.length() > 0) arguments.removeFirst();
|
||||||
auto isLauncher = qEnvironmentVariable("NKR_FROM_LAUNCHER") == "1";
|
auto isLauncher = qEnvironmentVariable("NKR_FROM_LAUNCHER") == "1";
|
||||||
@@ -649,6 +650,9 @@ void MainWindow::on_menu_exit_triggered() {
|
|||||||
if (exit_reason == 3) { // restart as admin
|
if (exit_reason == 3) { // restart as admin
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
WinCommander::runProcessElevated(program, arguments, "", WinCommander::SW_NORMAL, false);
|
WinCommander::runProcessElevated(program, arguments, "", WinCommander::SW_NORMAL, false);
|
||||||
|
#else
|
||||||
|
arguments << "-flag_linux_run_core_as_admin";
|
||||||
|
QProcess::startDetached(program, arguments);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
QProcess::startDetached(program, arguments);
|
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 != NekoRay::dataStore->spmode_vpn) {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (IS_NEKO_BOX_INTERNAL_TUN) {
|
if (IS_NEKO_BOX_INTERNAL_TUN) {
|
||||||
|
bool requestPermission = false;
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
if (!Windows_IsInAdmin()) {
|
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);
|
auto n = QMessageBox::warning(GetMessageBoxParent(), software_name, tr("Please run NekoBox as admin"), QMessageBox::Yes | QMessageBox::No);
|
||||||
if (n == QMessageBox::Yes) {
|
if (n == QMessageBox::Yes) {
|
||||||
this->exit_reason = 3;
|
this->exit_reason = 3;
|
||||||
@@ -710,8 +721,6 @@ void MainWindow::neko_set_spmode_vpn(bool enable, bool save) {
|
|||||||
}
|
}
|
||||||
neko_set_spmode_FAILED
|
neko_set_spmode_FAILED
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
// TODO check permission for Linux
|
|
||||||
} else {
|
} else {
|
||||||
if (NekoRay::dataStore->need_keep_vpn_off) {
|
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."));
|
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) {
|
auto make_title = [=](bool isTray) {
|
||||||
QStringList tt;
|
QStringList tt;
|
||||||
#ifdef Q_OS_WIN
|
if (!isTray && NekoRay::isAdmin()) tt << "[Admin]";
|
||||||
if (!isTray && Windows_IsInAdmin()) tt << "[Admin]";
|
|
||||||
#endif
|
|
||||||
if (select_mode) tt << "[" + tr("Select") + "]";
|
if (select_mode) tt << "[" + tr("Select") + "]";
|
||||||
if (!title_error.isEmpty()) tt << "[" + title_error + "]";
|
if (!title_error.isEmpty()) tt << "[" + title_error + "]";
|
||||||
if (NekoRay::dataStore->spmode_vpn) tt << "[VPN]";
|
if (NekoRay::dataStore->spmode_vpn) tt << "[VPN]";
|
||||||
|
|||||||
Reference in New Issue
Block a user