예제 #1
0
파일: Client.cs 프로젝트: DeCarabas/sudo
        public static int Run()
        {
            var stream = TryConnect(TimeSpan.FromSeconds(1));
            if (stream == null)
            {
                Elevate();
                stream = TryConnect(TimeSpan.FromSeconds(30));
                if (stream == null)
                {
                    Console.WriteLine("[[ Unable to contact sudo server! ]]");
                    return -7;
                }
            }

            using (stream)
            {
                var writer = new StreamWriter(stream);
                var reader = new StreamReader(stream);

                var programName = Environment.GetCommandLineArgs()[0];
                var commandLine = Environment.CommandLine;
                var index = commandLine.IndexOf(programName) + programName.Length;
                if (commandLine[index] == '"') { index++; } // Slight chance
                commandLine = commandLine.Substring(index);

                var request = new ExecuteRequest()
                {
                    ClientPid = Process.GetCurrentProcess().Id,
                    CommandLine = commandLine,
                    WorkingDirectory = Environment.CurrentDirectory
                };

                foreach(DictionaryEntry kvp in Environment.GetEnvironmentVariables())
                {
                    request.Environment.Add((string)kvp.Key, (string)kvp.Value);
                }

                request.Write(writer);
                writer.Flush();
                stream.Flush();

                var response = Int32.Parse(reader.ReadLine());
                var message = reader.ReadLine();

                if (message != "OK") { Console.WriteLine("Internal Error: {0}", message); }
                return response;
            }
        }
예제 #2
0
        public static ExecuteRequest Read( TextReader reader )
        {
            StringWriter writer = new StringWriter();

            writer.WriteLine( "Reading request..." );
            var request = new ExecuteRequest();

            var pidString = reader.ReadLine();
            if ( pidString == null ) { return null; }

            int pid;
            if ( !Int32.TryParse( pidString, out pid ) ) { return null; }
            request.ClientPid = pid;
            writer.WriteLine( "PID: {0}", request.ClientPid );

            request.WorkingDirectory = reader.ReadLine();
            if ( request.WorkingDirectory == null ) { return null; }
            writer.WriteLine( "Working Directory: {0}", request.WorkingDirectory );

            var environmentVariable = reader.ReadLine();
            while ( environmentVariable != String.Empty )
            {
                if ( environmentVariable == null ) { return null; }

                var environmentValue = reader.ReadLine();
                if ( environmentValue == null ) { return null; }

                writer.WriteLine( "Set: {0} = {1}", environmentVariable, environmentValue );
                request.Environment.Add( environmentVariable, environmentValue );

                environmentVariable = reader.ReadLine();
            }

            request.CommandLine = reader.ReadLine();
            if ( request.CommandLine == null ) { return null; }
            writer.WriteLine( "Command Line: {0}", request.CommandLine );

            writer.Flush();
            Tracer.WriteLine( writer.ToString() );

            return request;
        }
예제 #3
0
        static int Execute( ExecuteRequest request )
        {
            try
            {
                // Spawn off the child process.
                // Note that the command line here is magic. It *is* possible to screw it up. Please don't.
                //
                var startInfo = new ProcessStartInfo()
                {
                    FileName = String.Format( "\"{0}\"", Assembly.GetEntryAssembly().Location ),
                    Arguments = String.Format(
                        "-Exec {0} {1} {2}",
                        request.ClientPid,
                        Executor.MagicDelimiter,
                        request.CommandLine ),
                    WorkingDirectory = request.WorkingDirectory,
                    UseShellExecute = false,
                    CreateNoWindow = true
                };

                startInfo.EnvironmentVariables.Clear();
                foreach ( var kvp in request.Environment )
                {
                    startInfo.EnvironmentVariables.Add( kvp.Key, kvp.Value );
                }

                Tracer.WriteLine(
                    "SI FileName: {0} \nArgs: {1}\nWorking: {2}",
                    startInfo.FileName,
                    startInfo.Arguments,
                    startInfo.WorkingDirectory );

                var process = Process.Start( startInfo );

                process.WaitForExit();

                Tracer.WriteLine( "Done: {0}\n\n\n", process.ExitCode );
                return process.ExitCode;
            }
            finally
            {
                //
                // NOTE: There is a discontinuity here. Because we cannot rely on the finalizer we clear the "active
                //       server" count once this method completes. In order to make the counts sane, this object can be
                //       used only once.
                //
                lock ( ServerLock )
                {
                    ActiveServers--;
                    if ( ActiveServers == 0 )
                    {
                        NoActiveServers.Set();
                    }
                }
            }
        }