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); } }