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
maximilionus 2025-07-22 23:50:47 +03:00
parent ad5d21db5a
commit 7d6018638e
1 changed files with 22 additions and 48 deletions

View File

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