Login  
Search All Forums
Dart Home | PowerTCP SFTP & SSH for .NET | Custom Development Reply | PowerTCP SFTP & SSH for .NET Topics | Forums   
AuthorForum: PowerTCP SFTP & SSH for .NET
Topic: How do I abort SSH session?
raymegal

From: USA
Posts: 20
Member Since: 09/18/14
posted March 3, 2018 2:45 PM

I run the following:

<code lang="C#">
using System;
using System.Text.RegularExpressions;
using System.Timers;
using Dart.Ssh;

namespace SshSpike
{
  class Program
  {
    private static readonly Ssh Ssh1 = new Ssh();

    private static void Main()
    {
      var timer = new Timer(3000);
      timer.Elapsed += Timer_Elapsed;
      timer.Start();

      Ssh1.Data += ssh1_Data;
      Ssh1.Error += ssh1_Error;
      Ssh1.StateChanged += ssh1_StateChanged;

      Log("Start");
      try
      {
        //Connect
        Ssh1.Connection.RemoteEndPoint.HostNameOrAddress = "HOSTNAMEREPLACED";
        Ssh1.Connect();

        //Perform authentication (using username/password)
        Ssh1.Authenticate("USERNAME", "PASS");

        //Start session
        var session = Ssh1.StartShell();

        try
        {
          var buf = new byte[1000];
          var data = session.Read(buf);
          while (data.Count != 0)
          {
            if (!session.CanRead || Ssh1.State == ConnectionState.Closed)
            {
              break;
            }

            data = session.Read(buf);
            if (data.Count == 0)
            {
              break;
            }

            Ssh1.Marshal(data, session, "", null);
          }
        }
        catch (Exception ex)
        {
          Ssh1.Marshal(ex);
        }

        try
        {
          // Session has been closed.
          // This can execute when user type "exit" and the host closes the connection
          Ssh1.Marshal("", session);
        }
        catch
        {
          /* ignored */
        } // eat any error

        //Close session and connection
        session.Close();
        Ssh1.Close();
      }
      catch (Exception ex)
      {
        Ssh1.Marshal(ex);
      }

      Log("End");
    }

    private static void Log(string message)
    {
      Console.WriteLine($"{DateTime.Now:yyyyMMdd_HHmmss}: {message}");
    }

    private static void Timer_Elapsed(object sender, ElapsedEventArgs e)
    {
      Log("Timer elapsed");
      Ssh1.Close();
    }

    private static void ssh1_Data(object sender, SshDataEventArgs e)
    {
      // Ditch terminal control characters: https://superuser.com/questions/380772/removing-ansi-color-codes-from-text-stream
      var data = Regex.Replace(e.Data.ToString(), @"\x1b\[[0-9;]*[a-zA-Z]", "").Trim();
      // Ditch leading/trailing line feeds: https://stackoverflow.com/questions/2550672/regex-for-removing-leading-and-trailing-carriage-returns-and-line-feeds-from-a-s
      data = Regex.Replace(data, @"^[\r\n]+|\.|[\r\n]+$", "");
      Log(data);
    }

    private static void ssh1_Error(object sender, ErrorEventArgs e)
    {
      Log(e.GetException().Message);
    }

    private static void ssh1_StateChanged(object sender, EventArgs e)
    {
      Log($"State: {Ssh1.State}");
    }
  }
}
</code>

And it hangs during the Read. How can I abort the SSH session when a timer pops? I need to be able to break out of the Read when something external happens.
Nick B (Admin)

From: Utica, NY USA
Posts: 619
Member Since: 05/25/10

Extra Support Options
Custom Application Development

posted March 5, 2018 5:06 PM

Hello,

Please note that your server hostname, username and password were included in your code. If you would like us to remove it from your post, please let me know.

The program will block until the SessionStream.ReadTimeout is reached (which causes your "hang"). If you would like to abort the SessionStream, it would need to be from a thread other than the one that the Read operation is occurring on.

You could either move the Read operation to another thread, like is demonstrated here (just with a different Read overload) (the .Start() method is a built-in method to execute operations on a separate thread):
http://www.dart.com/help/ptsshnet/webframe.html#Dart.Ssh~Dart.Ssh.SessionStream~Read(Byte[]).html
Or if you want to use a timer (other than the built-in SessionStream.ReadTimeout), you could implement that on a separate thread. (In your provided code, you are implementing the timer on the main thread, not a separate thread)

Note that you are using Marshal() in what is currently a single-threaded application - Marshal() is only needed when executing code on a separate thread (unless you are just using it to separate out your read code and your Log code) (Marshal is used to raise an event on the main thread for such things as UI controls, as otherwise you would receive a cross-threading exception).
raymegal

From: USA
Posts: 20
Member Since: 09/18/14
posted March 5, 2018 5:50 PM

The server and user is a local Hyper-V instance that I use for testing, but you can ditch the server and user information from the post.

We're implementing an automated SSH session routine to replace an automated Telnet session routine built using your Telnet library. The use of Marshal is an artifact of the previous routine that depended upon the OnData event to capture the data. The Telnet routine successfully used its Abort method. I may still end up having to use Marshal since the Abort method isn't available in the SSH class and it looks like I will need to implement multiple threads to be able to successfully kill the SessionStream.Read operation.
Reply | PowerTCP SFTP & SSH for .NET Topics | Forums   
This site is powered by PowerTCP WebServer Tool PowerTCP WebServer for ActiveX