diff --git a/v2rayN/ServiceLib/Handler/CoreHandler.cs b/v2rayN/ServiceLib/Handler/CoreHandler.cs
index e181eb30..57e94557 100644
--- a/v2rayN/ServiceLib/Handler/CoreHandler.cs
+++ b/v2rayN/ServiceLib/Handler/CoreHandler.cs
@@ -259,7 +259,7 @@ namespace ServiceLib.Handler
return _config.TunModeItem.EnableTun
&& eCoreType == ECoreType.sing_box
&& Utils.IsLinux()
- && _config.TunModeItem.LinuxSudoPwd.IsNotEmpty()
+ //&& _config.TunModeItem.LinuxSudoPwd.IsNotEmpty()
;
}
@@ -275,7 +275,6 @@ namespace ServiceLib.Handler
return null;
}
- var isNeedSudo = mayNeedSudo && IsNeedSudo(coreInfo.CoreType);
try
{
Process proc = new()
@@ -294,14 +293,10 @@ namespace ServiceLib.Handler
}
};
+ var isNeedSudo = mayNeedSudo && IsNeedSudo(coreInfo.CoreType);
if (isNeedSudo)
{
- proc.StartInfo.FileName = $"/bin/sudo";
- proc.StartInfo.Arguments = $"-S {fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetConfigPath(configPath).AppendQuotes())}";
- proc.StartInfo.WorkingDirectory = null;
- proc.StartInfo.StandardInputEncoding = Encoding.UTF8;
- proc.StartInfo.RedirectStandardInput = true;
- Logging.SaveLog(proc.StartInfo.Arguments);
+ await RunProcessAsLinuxRoot(proc, fileName, coreInfo, configPath);
}
var startUpErrorMessage = new StringBuilder();
@@ -326,7 +321,7 @@ namespace ServiceLib.Handler
}
proc.Start();
- if (isNeedSudo)
+ if (isNeedSudo && _config.TunModeItem.LinuxSudoPwd.IsNotEmpty())
{
var pwd = DesUtils.Decrypt(_config.TunModeItem.LinuxSudoPwd);
await Task.Delay(10);
@@ -362,6 +357,37 @@ namespace ServiceLib.Handler
}
}
+ private async Task RunProcessAsLinuxRoot(Process proc, string fileName, CoreInfo coreInfo, string configPath)
+ {
+ var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetConfigPath(configPath).AppendQuotes())}";
+
+ //Prefer shell scripts
+ var shFilePath = Utils.GetBinPath("run_as_root.sh");
+ File.Delete(shFilePath);
+ var sb = new StringBuilder();
+ sb.AppendLine("#!/bin/sh");
+ sb.AppendLine(cmdLine);
+ await File.WriteAllTextAsync(shFilePath, sb.ToString());
+ await Utils.SetLinuxChmod(shFilePath);
+
+ //Replace command
+ var args = File.Exists(shFilePath) ? shFilePath : cmdLine;
+ if (_config.TunModeItem.LinuxSudoPwd.IsNotEmpty())
+ {
+ proc.StartInfo.FileName = $"/bin/sudo";
+ proc.StartInfo.Arguments = $"-S {args}";
+ }
+ else
+ {
+ proc.StartInfo.FileName = $"/bin/pkexec";
+ proc.StartInfo.Arguments = $"{args}";
+ }
+ proc.StartInfo.WorkingDirectory = null;
+ proc.StartInfo.StandardInputEncoding = Encoding.UTF8;
+ proc.StartInfo.RedirectStandardInput = true;
+ Logging.SaveLog(proc.StartInfo.Arguments);
+ }
+
private async Task KillProcess(Process? proc)
{
if (proc is null)
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
index 9fd66a6e..c281a4ad 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
@@ -1370,7 +1370,7 @@
Linux系统的sudo密码
- 密码已加密且只存储在本地文件中,无密码无法开启Tun
+ 密码已加密且只存储在本地文件中,无密码则每次都要输入
请先在Tun模式设置中设置sudo密码
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
index 0243c1f3..2d18ce2e 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
@@ -1370,7 +1370,7 @@
Linux系統的sudo密碼
- 密碼已加密且只儲存在本機檔案中,無密碼無法開啟Tun
+ 密碼已加密且只儲存在本機檔案中,無密碼則每次都要輸入
請先在Tun模式設定中設定sudo密碼
diff --git a/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs b/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
index 3298f636..89fbefc5 100644
--- a/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
@@ -416,16 +416,16 @@ namespace ServiceLib.ViewModels
// When running as a non-administrator, reboot to administrator mode
if (EnableTun && AllowEnableTun() == false)
{
- _config.TunModeItem.EnableTun = false;
if (Utils.IsWindows())
{
+ _config.TunModeItem.EnableTun = false;
Locator.Current.GetService()?.RebootAsAdmin();
+ return;
}
- else if (Utils.IsLinux())
- {
- NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordIsEmpty);
- }
- return;
+ //else if (Utils.IsLinux())
+ //{
+ // NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordIsEmpty);
+ //}
}
await ConfigHandler.SaveConfig(_config);
Locator.Current.GetService()?.Reload();