Exemplo n.º 1
0
        public override bool ExecuteAsUser(string command, string arguments, out ProcessExecuteStatus process_status, out string process_output, out string process_error, string user, SecureString password, Action <string> OutputDataReceived = null, Action <string> OutputErrorReceived = null, [CallerMemberName] string memberName = "", [CallerFilePath] string fileName = "", [CallerLineNumber] int lineNumber = 0)
        {
            CallerInformation caller = new CallerInformation(memberName, fileName, lineNumber);

            if (!this.IsConnected)
            {
                throw new InvalidOperationException("The SSH session is not connected.");
            }
            process_status = ProcessExecuteStatus.Unknown;
            process_output = "";
            process_error  = "";
            string c;

            if (password == null)
            {
                c = string.Format("-n -u {0} -s {1} {2}", user, command, arguments);
                return(this.Execute("sudo", c, out process_status, out process_output, out process_error));
            }
            StringBuilder shell_data = new StringBuilder();
            ShellStream   stream     = this.SshClient.CreateShellStream("dumb", 0, 0, 800, 600, 1024, new Dictionary <TerminalModes, uint> {
                { TerminalModes.ECHO, 0 }
            });

            stream.DataReceived += (s, d) => shell_data.Append(Encoding.UTF8.GetString(d.Data));
            c = string.Format("PAGER=cat su -c \"echo CMD_START && {0} {1} && echo CMD_SUCCESS || echo CMD_ERROR\" {2} || echo CMD_ERROR", command, arguments, user);
            byte[]    b  = Encoding.UTF8.GetBytes(c + this.LineTerminator);
            Stopwatch cs = new Stopwatch();

            cs.Start();
            IAsyncResult wr = stream.BeginWrite(b, 0, b.Length, new AsyncCallback(SshStreamWriteAsyncCallback), new KeyValuePair <string, ShellStream>(c, stream));

            stream.EndWrite(wr);
            bool got_password_prompt = false;

            ExpectAction[] got_password_prompt_action =
            {
                new ExpectAction("Password:"******"Unexpected response from server attempting to execute {0}: {1}", c, shell_data);
                return(false);
            }
            stream.EndWrite(wr);
            bool   cmd_success = false;
            string cmd_output  = string.Empty;

            ExpectAction[] cmd_actions =
            {
                new ExpectAction("CMD_ERROR",   (o) =>
                {
                    cmd_output  = o.Replace("CMD_ERROR", string.Empty);
                    cmd_success = false;
                }),
                new ExpectAction("CMD_SUCCESS", (o) =>
                {
                    cmd_output  = o.Replace("CMD_SUCCESS", string.Empty).Replace("CMD_START", string.Empty);
                    cmd_success = true;
                }),
            };
            er = stream.BeginExpect(new TimeSpan(0, 0, 5), new AsyncCallback(SshExpectAsyncCallback), new KeyValuePair <string, Stopwatch>(c, cs), cmd_actions);
            stream.EndExpect(er);
            if (!cmd_success)
            {
                process_status = ProcessExecuteStatus.Error;
                Debug(caller, "Execute {0} {1} returned non-zero exit code. Output: {2}.", command, arguments, cmd_output);
                return(false);
            }
            else
            {
                Debug(caller, "Execute {0} {1} returned zero exit code. Output: {2}.", command, arguments, cmd_output);
                process_status = ProcessExecuteStatus.Completed;
                process_output = cmd_output.Trim('\r', '\n');
                return(true);
            }
        }