private async Task <string> SendCommandSSH(string command, bool silent = false) { // Handle SSH login connection if (_sshUsername.Equals(String.Empty)) { _sshUsername = command; _terminalData.Add("Enter password:"******"Connecting..."); // Attempt connection _sshClient = new SshClient(_sshServer, _sshUsername, _terminalWindow._password); try { _sshClient.Connect(); _terminalWindow._passwordMode = false; _terminalWindow._password = String.Empty; var modes = new Dictionary <Renci.SshNet.Common.TerminalModes, uint>(); _sshStream = _sshClient.CreateShellStream("bgtTerm", 255, 50, 800, 600, 1024, modes); _sshStream.DataReceived += async(object sender, ShellDataEventArgs e) => { if (_sshStream != null && _sshStream.CanRead) { byte[] buffer = new byte[2048]; int i = 0; if ((i = await _sshStream.ReadAsync(buffer, 0, buffer.Length)) != 1) { _terminalData.Add(_sshClient.ConnectionInfo.Encoding.GetString(buffer, 0, i)); } } }; if (_sshClient.IsConnected) { _terminalData.Add("Connected to " + _sshServer); } else { _terminalData.Add("There was a problem connecting."); _sshMode = false; _sshUsername = String.Empty; } } catch (Exception e) { _terminalData.Add(e.Message); } } // Handle SSH commands else { if (_sshClient.IsConnected) { try { _sshStream.WriteLine(command); } catch (Exception e) { _terminalData.Add(e.Message); } } else { _terminalData.Add("You are no longer connected to SSH. Exiting."); _sshMode = false; _sshUsername = String.Empty; } } return(null); }
public static void HandleInput(string input, object sender = null) { sender = Program.sender ?? sender; StartupForm form = null; if (sender != null) { form = (StartupForm)sender; form.prgBar.Style = ProgressBarStyle.Blocks; form.prgBar.Value = 0; } string[] args = input.Split(' '); switch (args[0].ToLower()) { #region "help" case "help": Help(); break; #endregion #region "connect" case "connect": if (form != null) { form.prgBar.Maximum = 6; } try { host = args[1]; if (form != null) { form.prgBar.Value++; } Settings.Default.host = host; if (form != null) { form.prgBar.Value++; } username = args[2]; if (form != null) { form.prgBar.Value++; } password = args[3]; if (form != null) { form.prgBar.Value++; } } catch (IndexOutOfRangeException) { } connection = new SshClient( host: host, username: username, password: password); if (form != null) { form.prgBar.Value++; } connection.Connect(); if (form != null) { form.prgBar.Value++; } if (sender == null) { Console.WriteLine($"Connected to {host}'s user {username} with password {new string('*', password.Length)}"); } username = "******"; password = "******"; break; #endregion #region "disconnect" case "disconnect": if (form != null) { form.prgBar.Maximum = 1; } connection.Disconnect(); if (form != null) { form.prgBar.Value++; } break; #endregion #region "shutdown" case "shutdown": if (form != null) { form.prgBar.Maximum = 3; } using (ShellStream shellStream = connection.CreateShellStream("xterm", 255, 50, 800, 600, 1024, new Dictionary <Renci.SshNet.Common.TerminalModes, uint>())) { shellStream.Write("sudo poweroff\n"); if (form != null) { form.prgBar.Value++; } shellStream.Expect($"[sudo] password for {username}:"); if (form != null) { form.prgBar.Value++; } shellStream.Write($"{password}\n"); if (form != null) { form.prgBar.Value++; } } break; #endregion #region "gui" case "gui": FormTools.RunInNewThread(new StartupForm(), true); break; #endregion #region "ssh" case "ssh": if (form != null) { form.prgBar.Maximum = 2; } using (ShellStream shellStream = connection.CreateShellStream("xterm", 255, 50, 800, 600, 2048, new Dictionary <Renci.SshNet.Common.TerminalModes, uint>())) { Console.WriteLine(); if (form != null) { form.prgBar.Value++; } Console.Write(shellStream.Read()); if (form != null) { form.prgBar.Value++; } if (form != null) { form.prgBar.Style = ProgressBarStyle.Marquee; } while (true) { string streamInput = Console.ReadLine(); if (streamInput == "exit") { break; } shellStream.WriteLine(streamInput); Console.Write(shellStream.Read().TrimStart(streamInput.ToCharArray())); } } break; #endregion #region motor case "motor": HardwareController.MoveMotor(address: args[1], action: args[2]); break; #endregion case "run": if (HardwareController.State) { HardwareController.MoveMotor(HardwareController.MotorList["outB"], MotorMoveActions.run_forever); } break; case "": break; default: throw new NotSupportedException($"Unsupported Command: {input}"); } }
public void SendCommand(string cmd) { ss.WriteLine(cmd); evt.Reset(); }
public static void Execute(string app, string name, string goal, string min, string max, string profiling, string priority, string policy, string port, string args, string custom_arg1, string custom_arg2, string custom_arg3) { IDictionary <Renci.SshNet.Common.TerminalModes, uint> termkvp = new Dictionary <Renci.SshNet.Common.TerminalModes, uint>(); termkvp.Add(Renci.SshNet.Common.TerminalModes.ECHO, 53); ShellStream shellStream = Program.client.CreateShellStream("xterm", 80, 24, 800, 600, 1024, termkvp); string rep = shellStream.Expect(new Regex(@"[$>]")); switch (app) { case "Video Processing": shellStream.WriteLine("sudo orch-prewitt -n \"" + name + "\" -i \"/usr/share/orchestrator-prewitt-video/video1.avi\" -o \"/tmp/video1.avi\" -t " + goal); rep = shellStream.Expect(new Regex(@"([$#>:])")); //expect password or user prompt if (rep.Contains(":")) { shellStream.WriteLine(Program.password); } break; case "Numbers Addition": shellStream.WriteLine("sudo number-addition -a \"" + name + "\" -g " + goal + " -l " + min + " -h " + max + " -p " + profiling + " -n " + priority + " -r \"" + policy + "\" -o " + port + " " + args); rep = shellStream.Expect(new Regex(@"([$#>:])")); //expect password or user prompt if (rep.Contains(":")) { shellStream.WriteLine(Program.password); } break; case "Non Numbers Addition": shellStream.WriteLine("sudo non-number-addition -a \"" + name + "\" -g " + goal + " -l " + min + " -h " + max + " -p " + profiling + " -n " + priority + " -r \"" + policy + "\" -o " + port + " " + args); rep = shellStream.Expect(new Regex(@"([$#>:])")); //expect password or user prompt if (rep.Contains(":")) { shellStream.WriteLine(Program.password); } break; case "Matrix Multiplication": shellStream.WriteLine("sudo matrix-multiplication-on2 -c \"" + custom_arg1 + "\" -b \"" + custom_arg2 + "\" -d \"" + custom_arg3 + "\" -a \"" + name + "\" -g " + goal + " -l " + min + " -h " + max + " -p " + profiling + " -n " + priority + " -r \"" + policy + "\" -o " + port + " " + args); rep = shellStream.Expect(new Regex(@"([$#>:])")); //expect password or user prompt if (rep.Contains(":")) { shellStream.WriteLine(Program.password); } break; case "Image Processing Sobel": if (custom_arg1 == "XS - 75x75") { custom_arg1 = "image_xs"; } if (custom_arg1 == "XM - 200x200") { custom_arg1 = "image_xm"; } if (custom_arg1 == "CM - 500x500") { custom_arg1 = "image_cm"; } if (custom_arg1 == "HD - 1280x720") { custom_arg1 = "image_hd"; } shellStream.WriteLine("sudo image-sobel-on2 -b \"" + custom_arg1 + "\" -c \"" + custom_arg2 + "\" -d \"" + custom_arg3 + "\" -a \"" + name + "\" -g " + goal + " -l " + min + " -h " + max + " -p " + profiling + " -n " + priority + " -r \"" + policy + "\" -o " + port + " " + args); rep = shellStream.Expect(new Regex(@"([$#>:])")); //expect password or user prompt if (rep.Contains(":")) { shellStream.WriteLine(Program.password); } break; case "Workload Maker": shellStream.WriteLine("sudo workload-maker " + args); rep = shellStream.Expect(new Regex(@"([$#>:])")); //expect password or user prompt if (rep.Contains(":")) { shellStream.WriteLine(Program.password); } break; default: break; } }
public AppUI() { rootPan.Spacing = 6; var blurb1 = App.TextBlock; blurb1.TextAlignment = TextAlignment.Center; blurb1.Text = "Connect to an SSH server to access its shell"; var partcPanel = App.HorizontalStackPanel; partcPanel.HorizontalAlignment = HorizontalAlignment.Center; var hostBlurb = App.TextBlock; hostBlurb.Text = "Host:"; var hostField = App.TextBox; hostField.Width = 130; var portBlurb = App.TextBlock; portBlurb.Text = "Port:"; var portField = App.TextBox; portField.Width = 50; portField.Text = "22"; var userBlurb = App.TextBlock; userBlurb.Text = "Username:"******"Password:"******"Connect"; var disconnectBt = App.Button; disconnectBt.Content = "Disconnect"; disconnectBt.IsEnabled = false; partcPanel.Children.AddRange(new List <IControl> { hostBlurb, hostField, portBlurb, portField, userBlurb, userField, passBlurb, passField, connectBt, disconnectBt }); var logScrollable = App.ScrollableTextBlock; logScrollable.Background = Brushes.Transparent; logScrollable.Width = 900; logScrollable.Resources["ScrollBarThickness"] = 12; var logBox = App.TextBox; logBox.Width = logScrollable.Width - App.Margin.Top * 6; logBox.Height = 340; logBox.IsReadOnly = true; logBox.Foreground = Brushes.NavajoWhite; logBox.Background = Brushes.DarkBlue; logScrollable.Content = logBox; var commandPan = App.HorizontalFieldWithButton; commandPan.label.Text = "Input SSH command:"; commandPan.field.Width = 600; commandPan.field.IsEnabled = false; commandPan.field.KeyUp += (z, zz) => { if (zz.Key.Equals(Key.Enter)) { commandPan.button.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); } }; commandPan.holder.HorizontalAlignment = HorizontalAlignment.Center; commandPan.button.Content = "Send"; commandPan.button.IsEnabled = false; rootPan.Children.AddRange(new List <IControl> { blurb1, partcPanel, logScrollable, commandPan.holder }); connectBt.Click += async(z, zz) => { try { if (string.IsNullOrWhiteSpace(hostField.Text)) { throw new ArgumentNullException(); } ((App)Application.Current).LoadingBar.IsIndeterminate = true; client = await lib.ConnectToSshServerWithPassword(hostField.Text, int.Parse(portField.Text), userField.Text, passField[TextBox.TextProperty].ToString()); ss = client.CreateShellStream("", 1, 0, 0, 0, 1024 * 8); var dataObs = Observable.FromEventPattern <ShellDataEventArgs>(zzz => ss.DataReceived += zzz, zzz => ss.DataReceived -= zzz); logBox[!TextBlock.TextProperty] = dataObs.Select(zzz => logBox.Text + Encoding.Default.GetString(zzz.EventArgs.Data)).ToBinding(); logBox.Text = ""; connectBt.IsEnabled = false; disconnectBt.IsEnabled = true; commandPan.field.IsEnabled = true; commandPan.button.IsEnabled = true; hostField.IsEnabled = false; portField.IsEnabled = false; userField.IsEnabled = false; passField.IsEnabled = false; ((App)Application.Current).LoadingBar.IsIndeterminate = false; } catch (Exception e) { ((App)Application.Current).LoadingBar.IsIndeterminate = false; if (e is ArgumentNullException || e is ArgumentException || e is FormatException) { logBox.Text += "Empty or invalid connection parameter(s)." + "\n"; } else { logBox.Text += e.Message + "\n"; } } }; disconnectBt.Click += (z, zz) => { ss.Dispose(); client.Disconnect(); client.Dispose(); connectBt.IsEnabled = true; disconnectBt.IsEnabled = false; commandPan.field.IsEnabled = false; commandPan.button.IsEnabled = false; hostField.IsEnabled = true; portField.IsEnabled = true; userField.IsEnabled = true; passField.IsEnabled = true; }; commandPan.button.Click += (z, zz) => { ss.WriteLine(commandPan.field.Text); commandPan.field.Text = ""; }; }
public void WriteLineTest() { Session session = null; // TODO: Initialize to an appropriate value string terminalName = string.Empty; // TODO: Initialize to an appropriate value uint columns = 0; // TODO: Initialize to an appropriate value uint rows = 0; // TODO: Initialize to an appropriate value uint width = 0; // TODO: Initialize to an appropriate value uint height = 0; // TODO: Initialize to an appropriate value int maxLines = 0; // TODO: Initialize to an appropriate value IDictionary<TerminalModes, uint> terminalModeValues = null; // TODO: Initialize to an appropriate value ShellStream target = new ShellStream(session, terminalName, columns, rows, width, height, maxLines, terminalModeValues); // TODO: Initialize to an appropriate value string line = string.Empty; // TODO: Initialize to an appropriate value target.WriteLine(line); Assert.Inconclusive("A method that does not return a value cannot be verified."); }
/// <summary> /// Starts the user interaction. /// </summary> /// <param name="fsMonitor">The fs monitor.</param> /// <param name="sshClient">The SSH client.</param> /// <param name="sftpClient">The SFTP client.</param> /// <param name="shellStream">The shell stream.</param> /// <param name="verbOptions">The verb options.</param> private static void StartUserInteraction(FileSystemMonitor fsMonitor, SshClient sshClient, SftpClient sftpClient, ShellStream shellStream, MonitorVerbOptions verbOptions) { ForwardShellStreamInput = false; while (true) { var readKey = Console.ReadKey(true); if (readKey.Key == ConsoleKey.F1) { ForwardShellStreamInput = !ForwardShellStreamInput; if (ForwardShellStreamInput) { ConsoleManager.WriteLine(" >> Entered console input forwarding.", ConsoleColor.Green); ForwardShellStreamOutput = true; } else { ConsoleManager.WriteLine(" >> Left console input forwarding.", ConsoleColor.Red); } continue; } if (ForwardShellStreamInput) { if (readKey.Key == ConsoleKey.Enter) { shellStream.WriteLine(string.Empty); } else { shellStream.WriteByte((byte)readKey.KeyChar); } shellStream.Flush(); continue; } if (readKey.Key == ConsoleKey.Q) { break; } if (readKey.Key == ConsoleKey.C) { ConsoleManager.Clear(); continue; } if (readKey.Key == ConsoleKey.N) { CreateNewDeployment(sshClient, sftpClient, shellStream, verbOptions); continue; } if (readKey.Key == ConsoleKey.E) { RunSshClientCommand(sshClient, verbOptions); continue; } if (readKey.Key == ConsoleKey.S) { RunShellStreamCommand(shellStream, verbOptions); continue; } if (readKey.Key != ConsoleKey.H) { ConsoleManager.WriteLine("Unrecognized command '" + readKey.KeyChar + "' -- Press 'H' to get a list of available commands.", ConsoleColor.Red); } if (readKey.Key == ConsoleKey.H) { var helpColor = ConsoleColor.Cyan; ConsoleManager.WriteLine("Console help", helpColor); ConsoleManager.WriteLine(" H Prints this screen", helpColor); ConsoleManager.WriteLine(" Q Quits this application", helpColor); ConsoleManager.WriteLine(" C Clears the screen", helpColor); ConsoleManager.WriteLine(" N Force a deployment cycle", helpColor); ConsoleManager.WriteLine(" E Run the Pre-deployment command", helpColor); ConsoleManager.WriteLine(" S Run the Post-deployment command", helpColor); ConsoleManager.WriteLine(" F1 Toggle shell-interactive mode", helpColor); ConsoleManager.WriteLine(string.Empty); continue; } } }
/// <summary> /// Dump the input until we see a particular string in the returning text. /// </summary> /// <param name="s">The ssh stream to run against</param> /// <param name="matchText">The text to match - command is done and we return when we see it</param> /// <param name="failNow">Function that returns true if we should throw out right away</param> /// <param name="ongo">When we see a complete line, call this function. Defaults to null</param> /// <param name="secondsTimeout">How long should there be before we have a timeout.</param> /// <param name="refreshTimeout">If we see something back from the host, reset the timeout counter</param> /// <param name="crlfExpectedAtEnd">If the crlf is expected, then eat it when we see it. A command line prompt, for example, will not have this.</param> /// <param name="seeAndRespond">Dictionary of strings to look for and to respond to with further input.</param> private static async Task DumpTillFind(ShellStream s, SshClient client, string matchText, Action <string> ongo = null, int secondsTimeout = 60 *60, bool refreshTimeout = false, Func <bool> failNow = null, bool crlfExpectedAtEnd = false, Dictionary <string, string> seeAndRespond = null ) { /// <summary> /// How long to go before checking for update data from the stream. The actual timeout accuracy /// when refreshtimeout is set will depend on this. /// </summary> TimeSpan TimeoutGranularity = TimeSpan.FromSeconds(5); // Send back text we see if there is someone watching. // Don't send back the matched text. var lb = new LineBuffer(); if (ongo != null) { lb.AddAction(l => { if (!l.Contains(matchText)) { ongo(l); } }); } // Set when we see the text we are trying to match. bool gotmatch = false; // The Shell Stream works by looking for strings, and when it matches, performing a call out and returning. // The most obvious string to wait for is our matched string. var expectedMatchText = matchText + (crlfExpectedAtEnd ? LineBuffer.CrLf : ""); var matchText_action = new ExpectAction(expectedMatchText, l => { Trace.WriteLine($"DumpTillFill: Found expected Text: '{SummarizeText(l)}'"); lb.Add(l); gotmatch = true; }); Trace.WriteLine($"DumpTillFind: searching for text: {matchText} (with crlf: {crlfExpectedAtEnd})"); // Next is the end-of-line action. var matchEOL_action = new ExpectAction(new Regex("^.*" + LineBuffer.CrLf + "$"), l => { if (!gotmatch) { lb.Add(l); } }); // Finally, there are some see-and-then-send actions that might be present. When we see a match, send back some text. // This is an easy way to deal with a conversation (like a password request). var seeAndRespond_actions = seeAndRespond == null ? Enumerable.Empty <ExpectAction>() : seeAndRespond .Select(sr => new ExpectAction(sr.Key, whatMatched => { Trace.WriteLine($"DumpTillFill: Found seeAndRespond: {whatMatched}"); lb.Add(whatMatched); s.WriteLine(sr.Value); })); if (seeAndRespond != null) { foreach (var item in seeAndRespond) { Trace.WriteLine($"DumpTillFind: -> also looking for '{item.Key}' and will respond with '{item.Value}'"); } } // All the actions together var expect_actions = new[] { matchText_action, matchEOL_action } .Concat(seeAndRespond_actions) .ToArray(); // When is time up? If we are supposed to refresh the timeout then everytime the data changes in the buffer, we will want // to update the timeout. var timesUp = DateTime.Now + TimeSpan.FromSeconds(secondsTimeout); var streamDataLength = new ValueHasChanged <long>(() => s.Length); streamDataLength.Evaluate(); while (timesUp > DateTime.Now) { // Make sure the connection hasn't dropped. We won't get an exception later on if that hasn't happened. if (!client.IsConnected) { throw new SSHConnectionDroppedException($"Connection to {client.ConnectionInfo.Host} has been dropped."); } // Wait for some sort of interesting text to come back. var howLongToWait = MinTime(timesUp - DateTime.Now, TimeoutGranularity); var seenText = await Task.Factory.FromAsync( s.BeginExpect(howLongToWait, null, null, expect_actions), s.EndExpect); if (gotmatch) { break; } // Reset the timeout if data has come in and we are doing that. if (refreshTimeout && streamDataLength.HasChanged) { timesUp = DateTime.Now + TimeSpan.FromSeconds(secondsTimeout); } // Check to see if we should fail if (failNow != null && failNow()) { throw new SSHCommandInterruptedException("Calling routine requested termination of command"); } } // Done. IF there is anything that doesn't include a complete line in there, then dump it. lb.DumpRest(); if (!gotmatch) { var tmpString = lb.ToString(); Debug.WriteLine($"Waiting for '{matchText}' back from host and it was not seen inside of {secondsTimeout} seconds. Remaining in buffer: '{tmpString}'"); throw new TimeoutException($"Waiting for '{matchText}' back from host and it was not seen inside of {secondsTimeout} seconds. Remaining in buffer: '{tmpString}'"); } }
public void SendCommand(ShellStream stream, string cmd) { stream.WriteLine(cmd); var result = stream.Expect(PromptOrPwd, ExpectTimeout); if (result == null) { Error($"Timeout {Timeout} seconds reached executing {cmd}"); return; } if (PwdPrompt.IsMatch(result)) { stream.WriteLine(Password); var res = stream.Expect(Prompt, ExpectTimeout); if (res == null) { Error($"Timeout {Timeout} seconds reached executing {cmd}"); return; } result += res; } var echoCmd = "echo $?"; stream.WriteLine(echoCmd); var errorCode = stream.Expect(Prompt, ExpectTimeout); if (errorCode == null) { Error($"Timeout {Timeout} seconds reached executing {echoCmd}"); return; } if (errorCode.Contains(echoCmd)) { errorCode = errorCode.StringAfter(echoCmd); } errorCode = errorCode.TrimStart('\r', '\n'); if (!string.IsNullOrEmpty(errorCode)) { errorCode = errorCode.First().ToString(); } if (errorCode == "0") { foreach (var line in result.GetLines()) { Info(line); } } else if (result.Length > 0) { foreach (var line in result.GetLines()) { Error(line); } } }
private void SSH_KeyDown(object sender, KeyEventArgs e) { try { if (e.Control && e.KeyCode == Keys.V) { foreach (char Char in Clipboard.GetText(TextDataFormat.Text)) { shellStream.Write(Char.ToString()); localcommand += Char.ToString(); } return; } //remaining is key tab, and nano //if (e.KeyCode == Keys.Tab) //{ // shellStream.DataReceived -= ShellStream_DataReceived; // shellStream.WriteLine("ls"); // Thread.Sleep(500); // string s = reader.ReadToEnd(); // this.AppendText(s); // //to do tab work //} //if (e.KeyCode == Keys.Up) //{ // //shellStream.Write("\x24"); // //return; //} if (e.Control && e.KeyCode == Keys.C) { shellStream.Write("\x03"); return; } if (e.Control && e.KeyCode == Keys.X) { shellStream.Write("\x18"); return; } if (e.KeyCode == Keys.Back) { //local command handled in data received method shellStream.Write("\x08"); return; } if (e.KeyCode == Keys.Return) { TraverseCommand_forLocal(localcommand); localcommand = ""; shellStream.WriteLine(""); return; } if (e.KeyCode == Keys.Space) { shellStream.Write(" "); localcommand += " "; return; } if (e.KeyCode == Keys.OemPeriod) { shellStream.Write("."); localcommand += "."; return; } if (e.KeyCode == Keys.OemMinus) { if (e.Shift) { shellStream.Write("_"); localcommand += "_"; return; } shellStream.Write("-"); localcommand += "-"; return; } if (e.KeyCode == Keys.OemQuestion) { shellStream.Write("/"); localcommand += "/"; return; } if (e.KeyCode == Keys.Oem5) { shellStream.Write("\\"); localcommand += "\\"; return; } if (e.Shift && ((e.KeyValue >= 0x30 && e.KeyValue <= 0x39) || // numbers (e.KeyValue >= 0x41 && e.KeyValue <= 0x5A) // letters //|| (e.KeyValue >= 0x60 && e.KeyValue <= 0x69) // numpad )) { shellStream.Write(char.ConvertFromUtf32(e.KeyValue)); localcommand += char.ConvertFromUtf32(e.KeyValue); //shellStream.Write(e.KeyCode.ToString()); //localcommand += e.KeyCode.ToString(); return; } //MessageBox.Show(e.KeyValue.ToString()); //write alpha numberic values in small if ((e.KeyValue >= 0x30 && e.KeyValue <= 0x39) || // numbers (e.KeyValue >= 0x41 && e.KeyValue <= 0x5A) // letters //|| (e.KeyValue >= 0x60 && e.KeyValue <= 0x69)// numpad ) { shellStream.Write(char.ConvertFromUtf32(e.KeyValue).ToLower()); localcommand += char.ConvertFromUtf32(e.KeyValue).ToLower(); //shellStream.Write(e.KeyCode.ToString().ToLower()); //localcommand += e.KeyCode.ToString().ToLower(); return; } } catch (ObjectDisposedException ex) { MessageBox.Show("Connection failed"); throw ex; } catch (Exception ex) { throw ex; } }
private object SshCommsProcess(object userSpecific) { try { Thread.Sleep(1000); Debug.WriteInfo(string.Format("{0} attempting connection to {1}", GetType().Name, _address)); var firstFail = false; while (!_client.IsConnected && _reconnect) { try { ConnectionStatus = ClientStatus.AttemptingConnection; _client.Connect(); } catch { ConnectionStatus = ClientStatus.Disconnected; if (!firstFail) { CloudLog.Warn("{0} could not connect to {1}, will retry every 30 seconds until connected", GetType().Name, _address); firstFail = true; } Thread.Sleep(30000); } } if (!_client.IsConnected && !_reconnect) { _client.Dispose(); _client = null; ConnectionStatus = ClientStatus.Disconnected; return(null); } CloudLog.Notice("{0} Connected to {1}", GetType().Name, _address); _shell = _client.CreateShellStream("terminal", 80, 24, 800, 600, BufferSize); var buffer = new byte[BufferSize]; var dataCount = 0; try { while (_programRunning && _client.IsConnected) { while (_shell.CanRead && _shell.DataAvailable) { var incomingData = new byte[BufferSize]; var incomingDataCount = _shell.Read(incomingData, 0, incomingData.Length); #if DEBUG _stopWatch.Start(); Debug.WriteSuccess("Tesira rx {0} bytes", incomingDataCount); //Debug.WriteNormal(Debug.AnsiBlue + // Tools.GetBytesAsReadableString(incomingData, 0, incomingDataCount, true) + // Debug.AnsiReset); #endif if (!Connected && Encoding.ASCII.GetString(incomingData, 0, incomingDataCount) .Contains("Welcome to the Tesira Text Protocol Server...")) { _requestsSent.Clear(); _requestsAwaiting.Clear(); _sendQueue.Enqueue("SESSION set verbose true"); ConnectionStatus = ClientStatus.Connected; _keepAliveTimer = new CTimer(specific => { #if DEBUG Debug.WriteInfo(GetType().Name + " Sending KeepAlive"); #endif _client.SendKeepAlive(); }, null, KeepAliveTime, KeepAliveTime); } else if (Connected) { for (var i = 0; i < incomingDataCount; i++) { buffer[dataCount] = incomingData[i]; if (buffer[dataCount] == 10) { //skip } else if (buffer[dataCount] != 13) { dataCount++; } else { if (dataCount == 0) { continue; } var line = Encoding.UTF8.GetString(buffer, 0, dataCount); dataCount = 0; #if DEBUG Debug.WriteSuccess("Tesira Rx Line", Debug.AnsiPurple + line + Debug.AnsiReset); #endif TesiraMessage message = null; if (line == "+OK") { var request = _requestsAwaiting.TryToDequeue(); if (request != null) { #if DEBUG Debug.WriteInfo("Request Response Received", request); Debug.WriteSuccess(line); #endif message = new TesiraResponse(request, null); } } else if (line.StartsWith("+OK ")) { var request = _requestsAwaiting.TryToDequeue(); if (request != null) { #if DEBUG Debug.WriteInfo("Request Response Received", request); Debug.WriteSuccess(line); #endif message = new TesiraResponse(request, line.Substring(4)); } } else if (line.StartsWith("-ERR ")) { var request = _requestsAwaiting.TryToDequeue(); if (request != null) { #if DEBUG Debug.WriteInfo("Request Response Received", request); Debug.WriteError(line); #endif message = new TesiraErrorResponse(request, line.Substring(5)); } else { Debug.WriteError("Error received and request queue returned null!"); Debug.WriteError(line); Debug.WriteError("Clearing all queues!"); _requestsSent.Clear(); _requestsAwaiting.Clear(); } } else if (line.StartsWith("! ")) { #if DEBUG Debug.WriteWarn("Notification Received"); Debug.WriteWarn(line); #endif message = new TesiraNotification(line.Substring(2)); } else if (!_requestsSent.IsEmpty) { Debug.WriteWarn("Last sent request", _requestsSent.Peek()); if (_requestsSent.Peek() == line) { _requestsAwaiting.Enqueue(_requestsSent.Dequeue()); #if DEBUG Debug.WriteNormal("Now awaiting for response for command", line); #endif } } if (message != null && ReceivedData != null && message.Type != TesiraMessageType.ErrorResponse) { if (ReceivedData == null) { continue; } try { _timeOutCount = 0; ReceivedData(this, message); } catch (Exception e) { CloudLog.Exception(e, "Error calling event handler"); } } else if (message != null && message.Type == TesiraMessageType.ErrorResponse) { _timeOutCount = 0; CloudLog.Error("Error message from Tesira: \"{0}\"", message.Message); } } } } #if DEBUG _stopWatch.Stop(); Debug.WriteNormal("Time to process: {0} ms", _stopWatch.ElapsedMilliseconds); _stopWatch.Reset(); #endif CrestronEnvironment.AllowOtherAppsToRun(); } if (!_programRunning || !_client.IsConnected) { break; } #if DEBUG //Debug.WriteNormal(Debug.AnsiBlue + // string.Format( // "Shell Can Write = {0}, _sendQueue = {1}, _requestsSent = {2}, _requestsAwaiting = {3}", // _shell.CanWrite, _sendQueue.Count, _requestsSent.Count, // _requestsAwaiting.Count) + Debug.AnsiReset); #endif if (_shell.CanWrite && !_sendQueue.IsEmpty && _requestsSent.IsEmpty && _requestsAwaiting.IsEmpty) { var s = _sendQueue.Dequeue(); if (_keepAliveTimer != null && !_keepAliveTimer.Disposed) { _keepAliveTimer.Reset(KeepAliveTime, KeepAliveTime); } #if DEBUG Debug.WriteWarn("Tesira Tx", s); #endif _timeOutCount = 0; _shell.WriteLine(s); _requestsSent.Enqueue(s); Thread.Sleep(20); } else if (!_requestsSent.IsEmpty || !_requestsAwaiting.IsEmpty) { _timeOutCount++; if (_timeOutCount > 100) { CloudLog.Warn( "Error waiting to send requests in {0}, _requestsAwaiting.Count = {1}" + "and _requestsSent.Count = {2}. Clearing queues!", GetType().Name, _requestsAwaiting.Count, _requestsSent.Count); _requestsAwaiting.Clear(); _requestsSent.Clear(); _timeOutCount = 0; } Thread.Sleep(20); } } } catch (Exception e) { CloudLog.Exception(e); } _loggedIn = false; if (_keepAliveTimer != null && !_keepAliveTimer.Disposed) { _keepAliveTimer.Stop(); _keepAliveTimer.Dispose(); _keepAliveTimer = null; } if (_client != null && _client.IsConnected) { _client.Dispose(); _client = null; } CloudLog.Notice("{0} Disconnected from {1}", GetType().Name, _address); } catch (Exception e) { CloudLog.Exception(e, "Error in {0}.SshCommsProcess()", GetType().Name); } ConnectionStatus = ClientStatus.Disconnected; if (!_reconnect || !_programRunning) { return(null); } Thread.Sleep(1000); CloudLog.Notice("Attempting reconnect to Tesira at {0}", _address); ConnectionStatus = ClientStatus.AttemptingConnection; Connect(); return(null); }
protected void runMethod(object sender, EventArgs e) { ConnNfo = new ConnectionInfo(domain, 22, username, new AuthenticationMethod[] { new PasswordAuthenticationMethod(username, password) } ); sshclient = new SshClient(ConnNfo); sshclient.Connect(); if (combobox2.Active == 0) { // Change Password if (combobox4.Active == 0) { // Windows sshclient.CreateCommand("net user \"" + username + "\" " + password); if (checkbutton5.Active) { sshclient.CreateCommand("history -c"); } } else if (combobox4.Active == 1) { // Mac string reply = string.Empty; ShellStream ss = sshclient.CreateShellStream("dumb", 80, 24, 800, 600, 1024); ss.WriteLine("sudo passwd " + username); reply = ss.Expect("Password:"******"New password:"******""); } reply = ss.Expect("Retype new password:"******""); } if (checkbutton5.Active) { sshclient.CreateCommand("history -c"); } } else if (combobox4.Active == 2) { // Linux string reply = string.Empty; ShellStream ss = sshclient.CreateShellStream("dumb", 80, 24, 800, 600, 1024); ss.WriteLine("sudo passwd " + username); reply = ss.Expect("Password:"******"New password:"******""); } reply = ss.Expect("Retype new password:"******""); } if (checkbutton5.Active) { sshclient.CreateCommand("history -c"); } } else { throw new System.NotImplementedException(); } } else if (combobox2.Active == 1) { // New User throw new System.NotImplementedException(); } else { throw new System.NotImplementedException(); } sshclient.Disconnect(); if (checkbutton1.Active && footprintPath != "") { using (var sftp = new SftpClient(ConnNfo)) { string uploadfn = footprintPath; sftp.Connect(); sftp.ChangeDirectory("/"); using (var uplfileStream = System.IO.File.OpenRead(uploadfn)) { sftp.UploadFile(uplfileStream, uploadfn, true); } sftp.Disconnect(); } } }
private object SshCommsProcess(object userSpecific) { var errorOnConnect = false; try { Thread.Sleep(1000); CloudLog.Info("{0} attempting connection to {1}", GetType().Name, _address); var firstFail = false; while (!_client.IsConnected && _reconnect) { try { ConnectionStatus = SshClientStatus.AttemptingConnection; _client.Connect(); } catch { ConnectionStatus = SshClientStatus.Disconnected; if (!firstFail) { CloudLog.Warn("{0} could not connect to {1}, will retry every 30 seconds until connected", GetType().Name, _address); firstFail = true; } if (_threadWait.WaitOne(30000)) { CloudLog.Info("{0} - Signal sent to leave thread on attempt to connect", GetType().Name); _reconnect = false; break; } } } if (!_client.IsConnected && !_reconnect) { _client.Dispose(); _client = null; ConnectionStatus = SshClientStatus.Disconnected; return(null); } CloudLog.Notice("{0} Connected to {1}", GetType().Name, _address); _shell = _client.CreateShellStream("terminal", 80, 24, 800, 600, 100000); //_shell.DataReceived += (sender, args) => _threadWait.Set(); var data = string.Empty; try { while (_programRunning && _client.IsConnected) { while (_shell.CanRead && _shell.DataAvailable) { var bytes = new byte[100000]; var length = _shell.Read(bytes, 0, bytes.Length); #if DEBUG _stopWatch.Start(); Debug.WriteSuccess("Codec rx {0} bytes", length); #endif var incoming = Encoding.ASCII.GetString(bytes, 0, length); if (!_loggedIn && incoming.Contains("Failed to connect to system software")) { CloudLog.Error("Error received from codec at \"{0}\" on connect:\r\n{1}", _address, incoming); errorOnConnect = true; break; } #if DEBUG Debug.WriteNormal(Debug.AnsiBlue + incoming + Debug.AnsiReset); #endif data = data + incoming; if (!_loggedIn) { foreach (var line in Regex.Split(data, "\r\n|\r|\n")) { if (line == "*r Login successful") { _loggedIn = true; try { Debug.WriteSuccess("Connected!", "{0} logged into {1}", GetType().Name, _address); CloudLog.Info("{0} logged into {1}", GetType().Name, _address); _sendQueue.Enqueue(@"echo off"); var adapterType = _client.EthernetAdapter; var adapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(adapterType); var currentIp = CrestronEthernetHelper.GetEthernetParameter( CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterId); var assembly = Assembly.GetExecutingAssembly().GetName(); var softwareInfo = assembly.Name + " " + assembly.Version; var model = InitialParametersClass.ControllerPromptName; _sendQueue.Enqueue(string.Format( "xCommand Peripherals Connect ID: {0} Name: \"Crestron Control System\" HardwareInfo: \"{1}\" NetworkAddress: \"{2}\" SoftwareInfo: \"{3}\" Type: ControlSystem", _heartbeatId, string.Format("Crestron {0}", model), currentIp, softwareInfo)); _sendQueue.Enqueue(@"xFeedback register /Configuration"); _sendQueue.Enqueue(@"xFeedback register /Status/SystemUnit"); _sendQueue.Enqueue(@"xFeedback register /Status/Diagnostics"); _sendQueue.Enqueue(@"xFeedback register /Status/Audio"); _sendQueue.Enqueue(@"xFeedback register /Status/Standby"); _sendQueue.Enqueue(@"xFeedback register /Status/Video"); _sendQueue.Enqueue(@"xFeedback register /Status/Cameras"); _sendQueue.Enqueue(@"xFeedback register /Status/Call"); _sendQueue.Enqueue(@"xFeedback register /Status/Conference"); _sendQueue.Enqueue(@"xFeedback register /Status/UserInterface"); _sendQueue.Enqueue(@"xFeedback register /Status/Bookings"); _sendQueue.Enqueue(@"xFeedback register /Event/OutgoingCallIndication"); _sendQueue.Enqueue(@"xFeedback register /Event/IncomingCallIndication"); _sendQueue.Enqueue(@"xFeedback register /Event/CallSuccessful"); _sendQueue.Enqueue(@"xFeedback register /Event/CallDisconnect"); _sendQueue.Enqueue(@"xFeedback register /Event/Bookings"); _sendQueue.Enqueue(@"xFeedback register /Event/CallHistory"); _sendQueue.Enqueue(@"xFeedback register /Event/UserInterface/Extensions"); _sendQueue.Enqueue(@"xFeedback register /Event/UserInterface/Presentation/ExternalSource"); _sendQueue.Enqueue(@"xStatus"); _heartBeatTimer = new CTimer( specific => _sendQueue.Enqueue( string.Format("xCommand Peripherals HeartBeat ID: {0}", _heartbeatId)), null, 60000, 60000); ConnectionStatus = SshClientStatus.Connected; } catch (Exception e) { CloudLog.Exception(e); } } } data = string.Empty; } else if (data.Contains("** end")) { var chunks = Regex.Matches(data, @"(\*(\w) [\S\s]*?)(?=\*\* end)"); data = string.Empty; if (chunks.Count > 0) { foreach (Match chunk in chunks) { var type = ReceivedDataType.Status; switch (chunk.Groups[2].Value) { case "e": type = ReceivedDataType.Event; break; case "r": type = ReceivedDataType.Response; break; case "c": type = ReceivedDataType.Configuration; break; } OnReceivedData(this, type, chunk.Groups[1].Value); } } } #if DEBUG else { Debug.WriteWarn("Waiting for more data..."); } _stopWatch.Stop(); Debug.WriteNormal("Time to process: {0} ms", _stopWatch.ElapsedMilliseconds); _stopWatch.Reset(); #endif CrestronEnvironment.AllowOtherAppsToRun(); } if (errorOnConnect) { try { _client.Disconnect(); } catch (Exception e) { CloudLog.Warn("Error closing connection to codec after error, {0}", e.Message); } break; } if (!_programRunning || !_client.IsConnected) { break; } while (_shell.CanWrite && !_sendQueue.IsEmpty) { var s = _sendQueue.Dequeue(); #if DEBUG Debug.WriteWarn("Codec Tx", s); #endif _shell.WriteLine(s); } } CloudLog.Debug("{0} left while(connected) loop", Thread.CurrentThread.Name); } catch (ObjectDisposedException e) { CloudLog.Warn("{0} ObjectDisposedException, {1}, {2}", GetType().Name, string.IsNullOrEmpty(e.ObjectName) ? "unknown" : e.ObjectName, e.Message); } catch (Exception e) { CloudLog.Exception(e, "Error handling comms process"); } _loggedIn = false; try { if (_heartBeatTimer != null && !_heartBeatTimer.Disposed) { _heartBeatTimer.Stop(); _heartBeatTimer.Dispose(); } if (_client != null) { CloudLog.Info("Disposing {0}", _client.ToString()); _client.Dispose(); _client = null; } } catch (Exception e) { CloudLog.Exception(e, "Error trying to dispose items in leaving thread"); } CloudLog.Notice("{0} Disconnected from {1}", GetType().Name, _address); } catch (Exception e) { CloudLog.Exception(e, "Error in {0}.SshCommsProcess()", GetType().Name); } ConnectionStatus = SshClientStatus.Disconnected; if (errorOnConnect) { CloudLog.Warn("Error message while connecting to {0}, Disconnected and will retry in 60 seconds", _address); if (_threadWait.WaitOne(60000)) { CloudLog.Info("{0} - Signal sent to leave thread on attempt to connect", GetType().Name); _reconnect = false; } } if (!_reconnect) { CloudLog.Notice("Leaving connect thread for codec at {0}", _address); return(null); } CloudLog.Notice("Waiting for 10 seconds before reconnect attempt to {0}", _address); if (_threadWait.WaitOne(10000)) { CloudLog.Info("{0} - Signal sent to leave thread on attempt to connect", GetType().Name); _reconnect = false; return(null); } CloudLog.Notice("Attempting reconnect to codec at {0}", _address); ConnectionStatus = SshClientStatus.AttemptingConnection; Connect(); return(null); }
/// <summary> /// Runs in a new thread /// </summary> /// <param name="connectionData">The connection data.</param> /// <param name="command">The command string.</param> private void sshThreadRunner(ConnectionData connectionData, string command) { using (SshClient sshClient = new SshClient(connectionData.Hostname, 22, connectionData.UserName, connectionData.Password)) { try { sshClient.ErrorOccurred += SshClient_ErrorOccurred; this._eventaggregator.GetEvent <SshClientStatusMessageEvent>().Publish(new SshClientStatusMessage() { Sender = this, MessageType = SshClientStatusMessageType.Connecting }); sshClient.Connect(); IDictionary <Renci.SshNet.Common.TerminalModes, uint> termkvp = new Dictionary <Renci.SshNet.Common.TerminalModes, uint>(); termkvp.Add(Renci.SshNet.Common.TerminalModes.ECHO, 53); ShellStream shellStream = sshClient.CreateShellStream("text", 200, 24, 800, 600, 1024, termkvp); Console.WriteLine("Verbunden mit: {0}", connectionData.Hostname); this._eventaggregator.GetEvent <SshClientStatusMessageEvent>().Publish(new SshClientStatusMessage() { Sender = this, MessageType = SshClientStatusMessageType.Connected, MessageText = string.Format("Connected to: {0}", connectionData.Hostname) }); string response = shellStream.Expect(new Regex(@"[$>]")); //expect user prompt shellStream.WriteLine(command); Thread.Sleep(500); while (!this._terminateThread) { Console.WriteLine("Still listening on ssh..."); // Todo: read the data //response = shellStream.Expect(new Regex(@"[$>]")); //expect user prompt response = shellStream.Expect(new Regex(@"([$#>:])")); //expect password or user prompt //check to send password if (response.Contains(string.Format("password for {0}:", connectionData.UserName))) { //send password shellStream.WriteLine(connectionData.Password); } else { ParseResponseData(response); } Thread.Sleep(10); } } catch (ThreadAbortException e) { this._terminateThread = true; this._isSessionRunning = false; this._eventaggregator.GetEvent <SshClientStatusMessageEvent>().Publish(new SshClientStatusMessage() { Sender = this, MessageType = SshClientStatusMessageType.Disconnected }); Thread.ResetAbort(); } catch (Exception e) { this._terminateThread = true; this._eventaggregator.GetEvent <SshClientStatusMessageEvent>().Publish(new SshClientStatusMessage() { Sender = this, MessageType = SshClientStatusMessageType.ConnectionError, MessageText = e.Message }); sshClient.Disconnect(); this._isSessionRunning = false; } sshClient.Disconnect(); this._eventaggregator.GetEvent <SshClientStatusMessageEvent>().Publish(new SshClientStatusMessage() { Sender = this, MessageType = SshClientStatusMessageType.Disconnected }); this._isSessionRunning = false; } }