Issue: Cannot reuse Session across Sftp, Ssh, Scp, etc

+1 vote
asked Apr 6, 2010 by Stephen Zebo (260 points)
edited Mar 26, 2011

The object Sftp, Ssh, Scp have a property named Session, which allows access to the SSH session. However there is no set implementation for this property. There is no way to open one session and use it for Sftp, Ssh, Scp simultaneously. This is an issue because there are servers with limitation on the number of sessions you can open at the same time.

Any comments guys?

2 Answers

0 votes
answered Apr 6, 2010 by Lukas Pokorny (102,210 points)
edited May 21, 2010

Note: This answer only applies to old releases of Rebex SFTP and SSH components. Check out this answer for newer versions.

Instances of Sftp object can be initialized to use an existing SSH session, but Ssh and Scp don't have this capability yet. However, adding this functionality would be quite simply and we can add it into the next release if needed.

string serverName = "tcharles";
string userName = "tester0";
string password = "psw4tester";

// create a SSH session (alternatively, you can use the Session property
// of Sftp, Ssh or Scp object and skip Connect and Authenticate methods)
SshSession ssh = new SshSession();
ssh.Connect(serverName);
ssh.Authenticate(userName, password);

// create an SFTP channel
SshChannel channel1 = ssh.OpenSession();
channel1.RequestSubsystem("sftp");

// initialize an SFTP session based on the channel
Sftp sftp1 = new Sftp();
sftp1.Bind(channel1.ToSocket());
Console.WriteLine(string.Join("\n", sftp1.GetRawList("*.txt")));

// create another SFTP channel
SshChannel channel2 = ssh.OpenSession();
channel2.RequestSubsystem("sftp");

// create an SFTP session based on another channel
Sftp sftp2 = new Sftp();            
sftp2.Bind(channel2.ToSocket());
Console.WriteLine(string.Join("\n", sftp2.GetRawList("*.txt")));

// both SFTP sessions are already usable - there is no need to
// call Connect and Login methods
...

In the next version, we would add a new overload of the Bind method that accepts an SshSession object, making the code simpler (no need to bother with SshChannel any more).

With the current version, you can initialize an Ssh instance first and then create Sftp instance that shares the same SSH session. If you need more, please let us know and we will send you a beta when this feature is available.

commented Apr 6, 2010 by Stephen Zebo (260 points)
It is good to know the Sftp object is covered. However there is indeed an issue with the Ssh and Scp objects. If the change is easy to make, when can you do a release? Can you make a release before the end of the week? If not, can you do a temporary suggestion? Like code, which sets the state of the internal (private) members of the Ssh and Scp using reflection, so they think they are already connected to a session.
commented Apr 6, 2010 by Lukas Pokorny (102,210 points)
Yes, we can make a development release before the end of the week. Would you like a time-limited trial release or have you already purchased a license?
commented Apr 9, 2010 by Stephen Zebo (260 points)
I was able to hack it using reflection for now. Here is what I did: sshType.InvokeMember( "_session", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance, null, client, new object[] { m_session } ); sshType.InvokeMember( "_authenticated",BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance, null, client, new object[] { true } ); I know this is not recommended, but for now it gets the job done. I will wait for the official release. Thank you for your efforts Lukas.
commented Apr 9, 2010 by Lukas Pokorny (102,210 points)
I actually sent a link to the current development build of Rebex SSH Pack to the e-mail associated with your account, have you received it?
commented Apr 9, 2010 by Lukas Pokorny (102,210 points)
Your current approach is OK (although of course not recommended), but be careful not to call Disconnect or Dispose on Sftp/Ssh/Scp objects because that would close the session.
commented May 21, 2010 by Lukas Pokorny (102,210 points)
In the latest release, Sftp/Ssh/Scp objects can be bound directly to an SshSession.
0 votes
answered May 21, 2010 by Lukas Pokorny (102,210 points)
edited May 21, 2010

Since build 3793, instances of Sftp, Scp and Ssh objects can be initialized to use an existing SSH session:

string serverName = "tcharles";
string userName = "tester0";
string password = "psw4tester";

// create a SSH session (alternatively, you can use the Session property
// of Sftp, Ssh or Scp object and skip Connect and Authenticate methods)
SshSession ssh = new SshSession();
ssh.Connect(serverName);
ssh.Authenticate(userName, password);

// initialize an SFTP session based on the channel
Sftp sftp1 = new Sftp();
sftp1.Bind(ssh);
Console.WriteLine(string.Join("\n", sftp1.GetRawList("*.txt")));

// create an SFTP session based on another channel
Sftp sftp2 = new Sftp();            
sftp2.Bind(ssh);
Console.WriteLine(string.Join("\n", sftp2.GetRawList("*.txt")));

// both SFTP sessions are already usable - there is no need to
// call Connect and Login methods
...
...