// // Copyright (c) 2010-2018 Antmicro // Copyright (c) 2011-2015 Realtime Embedded // // This file is licensed under the MIT License. // Full license text is available in 'licenses/MIT.txt'. // using System; using System.Diagnostics; namespace Antmicro.Renode.Utilities { /// /// Sudo tools. Set of methods related to the process elevation. /// public static class SudoTools { /// /// Wraps the command into a sudo-tool call if necessary, creates a new Process object and exectues it. /// /// /// Checks whether user is root. If it is exectues command, id not tries to elevate priviledged and run the command. /// /// The sudo execute. /// Command. /// Command's arguments. /// Optional description. public static Process EnsureSudoExecute(string command, string arguments = "", string description = "") { Process process; process = Misc.IsRoot ? Process.Start(command, arguments) : SudoExecute(command + " " + arguments, description); return process; } /// /// Tries to wrap existing Process, with supported sudo tool. It switched the command's filename and arguments, and wraps them /// into a call to the supported sudo tool, if it's found. /// /// Process to be elevated. /// Process description. public static void EnsureSudoProcess(Process process, string description = "") { if(Misc.IsRoot) { return; } Process sudoProcess = process; string sudoName = FindSudoToolName(); if(string.IsNullOrWhiteSpace(sudoProcess.StartInfo.FileName)) { throw new ArgumentException("EnsureSudoProcess needs to work on a process with initliazed StartInfo.FileName."); } var command = sudoProcess.StartInfo.FileName + " " + sudoProcess.StartInfo.Arguments; sudoProcess.StartInfo.Arguments = SudoDecorateCommand(sudoName, command, description); sudoProcess.StartInfo.FileName = sudoName; } /// /// Finds the name of the sudo tool. /// /// true, if sudo tool name was found, false otherwise. /// Sudo tool name, if found. private static bool TryFindSudoToolName(out string name) { name = default(string); foreach(var nameToCheck in knownToolNames) { if(Misc.IsCommandAvaialble(nameToCheck)) { name = nameToCheck; return true; } } return false; } /// /// Finds the name of the sudo tool. Throwing version of . /// /// The sudo tool name. private static string FindSudoToolName() { string name; if(!TryFindSudoToolName(out name)) { throw new PlatformNotSupportedException( String.Format("Error: No supported sudo tool found. Supported tools are {0}.", string.Join(", ", knownToolNames)) ); } return name; } /// /// Tries to find sudo tool, and execute the command with elevated rigths. /// /// The Process object, after the execution. /// Command. /// Description. private static Process SudoExecute(string command, string description = "") { string sudoName = FindSudoToolName(); Process process; command = SudoDecorateCommand(sudoName, command, description); process = Process.Start(sudoName, command); return process; } /// /// Decorates the command for a specific sudo tool. /// /// The decorated command. /// Sudo tool name. /// Command to be decorated. /// Description. private static string SudoDecorateCommand(string sudoName, string command, string description = "") { string result; switch(sudoName) { // Tool specific adjustments. case "gksudo": result = string.Format(@"-D ""{0}"" ""{1}""", description, command); break; case "kdesudo": result = string.Format(@"-c ""{0}"" --comment ""{1}""", command, description); break; case "pkexec": // We do nothing, because 'pkexec' (version 0.105) doesn't accept description as a parameter. default: result = command; break; } return result; } /// /// List of supported tool names. /// private static string[] knownToolNames = { "gksudo", "kdesudo", "pkexec" }; } }