mirror of https://github.com/2dust/v2rayN
Robust privilege elevation on Unix platform
This improves the elevation on Linux/macOS platforms, that now will work in 100% of the calls. Fixes the periodical tunnel start/stop problems. And also a few sudo call enhancements: - '-k' clears the credentials for current session, will require the password input on the next call. - '-p' removes the password prompt. - '--' mark the end of command options in Unix style.pull/7639/head
parent
ad5d21db5a
commit
7d6018638e
|
@ -32,57 +32,31 @@ public class CoreAdminHandler
|
||||||
var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetBinConfigPath(configPath).AppendQuotes())}";
|
var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetBinConfigPath(configPath).AppendQuotes())}";
|
||||||
var shFilePath = await CreateLinuxShellFile(cmdLine, "run_as_sudo.sh");
|
var shFilePath = await CreateLinuxShellFile(cmdLine, "run_as_sudo.sh");
|
||||||
|
|
||||||
Process proc = new()
|
var cmdTask = Cli.Wrap(shFilePath)
|
||||||
{
|
.WithWorkingDirectory(Utils.GetBinConfigPath())
|
||||||
StartInfo = new()
|
.WithStandardInputPipe(PipeSource.FromString(AppHandler.Instance.LinuxSudoPwd))
|
||||||
{
|
.WithStandardOutputPipe(PipeTarget.ToDelegate(
|
||||||
FileName = shFilePath,
|
s =>
|
||||||
Arguments = "",
|
{
|
||||||
WorkingDirectory = Utils.GetBinConfigPath(),
|
if (!string.IsNullOrEmpty(s))
|
||||||
UseShellExecute = false,
|
UpdateFunc(false, s + Environment.NewLine);
|
||||||
RedirectStandardInput = true,
|
}))
|
||||||
RedirectStandardOutput = true,
|
.WithStandardErrorPipe(PipeTarget.ToDelegate(
|
||||||
RedirectStandardError = true,
|
s =>
|
||||||
CreateNoWindow = true,
|
{
|
||||||
StandardInputEncoding = Encoding.UTF8,
|
if (!string.IsNullOrEmpty(s))
|
||||||
StandardOutputEncoding = Encoding.UTF8,
|
UpdateFunc(false, s + Environment.NewLine);
|
||||||
StandardErrorEncoding = Encoding.UTF8,
|
}))
|
||||||
}
|
.WithValidation(CommandResultValidation.None)
|
||||||
};
|
.ExecuteAsync();
|
||||||
|
|
||||||
proc.OutputDataReceived += (sender, e) =>
|
Task.Delay(100)
|
||||||
{
|
if (cmdTask.ProcessId is null)
|
||||||
if (e.Data.IsNotEmpty())
|
|
||||||
{
|
|
||||||
UpdateFunc(false, e.Data + Environment.NewLine);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
proc.ErrorDataReceived += (sender, e) =>
|
|
||||||
{
|
|
||||||
if (e.Data.IsNotEmpty())
|
|
||||||
{
|
|
||||||
UpdateFunc(false, e.Data + Environment.NewLine);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
proc.Start();
|
|
||||||
proc.BeginOutputReadLine();
|
|
||||||
proc.BeginErrorReadLine();
|
|
||||||
|
|
||||||
await Task.Delay(10);
|
|
||||||
await proc.StandardInput.WriteLineAsync();
|
|
||||||
await Task.Delay(10);
|
|
||||||
await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
|
|
||||||
|
|
||||||
await Task.Delay(100);
|
|
||||||
if (proc is null or { HasExited: true })
|
|
||||||
{
|
|
||||||
throw new Exception(ResUI.FailedToRunCore);
|
throw new Exception(ResUI.FailedToRunCore);
|
||||||
}
|
|
||||||
|
|
||||||
_linuxSudoPid = proc.Id;
|
_linuxSudoPid = cmdTask.ProcessId;
|
||||||
|
|
||||||
return proc;
|
return Process.GetProcessById(_linuxSudoPid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task KillProcessAsLinuxSudo()
|
public async Task KillProcessAsLinuxSudo()
|
||||||
|
@ -115,7 +89,7 @@ public class CoreAdminHandler
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sb.AppendLine($"sudo -S {cmdLine}");
|
sb.AppendLine($"sudo -S -k -p '' -- {cmdLine}");
|
||||||
}
|
}
|
||||||
|
|
||||||
await File.WriteAllTextAsync(shFilePath, sb.ToString());
|
await File.WriteAllTextAsync(shFilePath, sb.ToString());
|
||||||
|
|
Loading…
Reference in New Issue