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();