Beispiel #1
0
        /// Starts a cache session
        private async Task <int> RunUsingElevatedService(ElevationRequest elevationRequest)
        {
            Logger.Instance.Log($"Using Console mode {elevationRequest.Mode}", LogLevel.Debug);

            var cmd = CommandToRun.FirstOrDefault();

            Rpc.Connection connection = null;
            try
            {
                connection = await ConnectStartElevatedService().ConfigureAwait(false);

                if (connection == null) // service is not running or listening.
                {
                    Logger.Instance.Log("Unable to connect to the elevated service.", LogLevel.Error);
                    return(Constants.GSUDO_ERROR_EXITCODE);
                }

                var renderer = GetRenderer(connection, elevationRequest);
                await WriteElevationRequest(elevationRequest, connection).ConfigureAwait(false);

                ConnectionKeepAliveThread.Start(connection);

                var exitCode = await renderer.Start().ConfigureAwait(false);

                return(exitCode);
            }
            finally
            {
                connection?.Dispose();
            }
        }
Beispiel #2
0
        public async Task <int> Execute()
        {
            //Logger.Instance.Log("Params: " + Newtonsoft.Json.JsonConvert.SerializeObject(this), LogLevel.Debug);

            var  currentProcess = System.Diagnostics.Process.GetCurrentProcess();
            bool emptyArgs      = string.IsNullOrEmpty(CommandToRun.FirstOrDefault());

            CommandToRun = ArgumentsHelper.AugmentCommand(CommandToRun.ToArray());
            bool isWindowsApp = ProcessFactory.IsWindowsApp(CommandToRun.FirstOrDefault());
            var  consoleMode  = GetConsoleMode(isWindowsApp);

            if (!RunningAsDesiredUser())
            {
                CommandToRun = AddCopyEnvironment(CommandToRun);
            }
            var exeName = CommandToRun.FirstOrDefault();

            var elevationRequest = new ElevationRequest()
            {
                FileName         = exeName,
                Arguments        = GetArguments(),
                StartFolder      = Environment.CurrentDirectory,
                NewWindow        = GlobalSettings.NewWindow,
                Wait             = (!isWindowsApp && !GlobalSettings.NewWindow) || GlobalSettings.Wait,
                Mode             = consoleMode,
                ConsoleProcessId = currentProcess.Id,
                Prompt           = consoleMode != ElevationRequest.ConsoleMode.Raw || GlobalSettings.NewWindow ? GlobalSettings.Prompt : GlobalSettings.RawPrompt
            };

            Logger.Instance.Log($"Command to run: {elevationRequest.FileName} {elevationRequest.Arguments}", LogLevel.Debug);

            if (elevationRequest.Mode == ElevationRequest.ConsoleMode.VT)
            {
                elevationRequest.ConsoleWidth  = Console.WindowWidth;
                elevationRequest.ConsoleHeight = Console.WindowHeight;

                if (TerminalHelper.IsConEmu())
                {
                    elevationRequest.ConsoleWidth--; // weird ConEmu/Cmder fix
                }
            }

            if (RunningAsDesiredUser()) // already elevated or running as correct user. No service needed.
            {
                if (emptyArgs && !GlobalSettings.NewWindow)
                {
                    Logger.Instance.Log("Already elevated (and no parameters specified). Exiting...", LogLevel.Error);
                    return(Constants.GSUDO_ERROR_EXITCODE);
                }

                Logger.Instance.Log("Already elevated. Running in-process", LogLevel.Debug);

                // No need to escalate. Run in-process

                if (elevationRequest.Mode == ElevationRequest.ConsoleMode.Raw && !elevationRequest.NewWindow)
                {
                    if (!string.IsNullOrEmpty(GlobalSettings.RawPrompt.Value))
                    {
                        Environment.SetEnvironmentVariable("PROMPT", Environment.ExpandEnvironmentVariables(GlobalSettings.RawPrompt.Value));
                    }
                }
                else
                {
                    if (!string.IsNullOrEmpty(GlobalSettings.Prompt.Value))
                    {
                        Environment.SetEnvironmentVariable("PROMPT", Environment.ExpandEnvironmentVariables(GlobalSettings.Prompt.Value));
                    }
                }

                if (GlobalSettings.NewWindow)
                {
                    using (Process process = ProcessFactory.StartDetached(exeName, GetArguments(), Environment.CurrentDirectory, false))
                    {
                        if (elevationRequest.Wait)
                        {
                            process.WaitForExit();
                            var exitCode = process.ExitCode;
                            Logger.Instance.Log($"Elevated process exited with code {exitCode}", exitCode == 0 ? LogLevel.Debug : LogLevel.Info);
                            return(exitCode);
                        }
                        return(0);
                    }
                }
                else
                {
                    using (Process process = ProcessFactory.StartInProcessAtached(exeName, GetArguments()))
                    {
                        process.WaitForExit();
                        var exitCode = process.ExitCode;
                        Logger.Instance.Log($"Elevated process exited with code {exitCode}", exitCode == 0 ? LogLevel.Debug : LogLevel.Info);
                        return(exitCode);
                    }
                }
            }
            else
            {
                Logger.Instance.Log($"Using Console mode {elevationRequest.Mode}", LogLevel.Debug);
                var callingPid = GetCallingPid(currentProcess);
                var callingSid = WindowsIdentity.GetCurrent().User.Value;
                Logger.Instance.Log($"Caller PID: {callingPid}", LogLevel.Debug);
                Logger.Instance.Log($"Caller SID: {callingSid}", LogLevel.Debug);

                var cmd = CommandToRun.FirstOrDefault();

                var            rpcClient  = GetClient(elevationRequest);
                Rpc.Connection connection = null;

                try
                {
                    try
                    {
                        connection = await rpcClient.Connect(elevationRequest, null, 300).ConfigureAwait(false);
                    }
                    catch (System.IO.IOException) { }
                    catch (TimeoutException) { }
                    catch (Exception ex)
                    {
                        Logger.Instance.Log(ex.ToString(), LogLevel.Warning);
                    }

                    if (connection == null) // service is not running or listening.
                    {
                        // Start elevated service instance
                        if (!StartElevatedService(currentProcess, callingPid, callingSid))
                        {
                            return(Constants.GSUDO_ERROR_EXITCODE);
                        }

                        connection = await rpcClient.Connect(elevationRequest, callingPid, 5000).ConfigureAwait(false);
                    }

                    if (connection == null) // service is not running or listening.
                    {
                        Logger.Instance.Log("Unable to connect to the elevated service.", LogLevel.Error);
                        return(Constants.GSUDO_ERROR_EXITCODE);
                    }

                    await WriteElevationRequest(elevationRequest, connection).ConfigureAwait(false);

                    ConnectionKeepAliveThread.Start(connection);

                    var renderer = GetRenderer(connection, elevationRequest);
                    var exitCode = await renderer.Start().ConfigureAwait(false);

                    if (!(elevationRequest.NewWindow && !elevationRequest.Wait))
                    {
                        Logger.Instance.Log($"Elevated process exited with code {exitCode}", exitCode == 0 ? LogLevel.Debug : LogLevel.Info);
                    }

                    return(exitCode);
                }
                finally
                {
                    connection?.Dispose();
                }
            }
        }