Subject: Re: SSH client is not reading full data if executed command generates big output

Re: SSH client is not reading full data if executed command generates big output

From: Peter Stuge <>
Date: Tue, 30 Oct 2018 11:07:21 +0000

Subrata Dasgupta wrote:
> My intention is to run several commands on a small router like device.
> The device provide a restricted environment and allows user to run only
> specific set of commands. Some commands may also have sub-commands, for
> an example until and unless &#39;enable&#39; command is executed user
> are not allowed to execute few commands. One more example of sub-command
> is, until and unless &quot;configure terminal&quot; command is executed
> users are not allowed to run any configuration related commands.

Oh now I understand. Thanks for the explanation.

> So I need to retain the state otherwise I can not execute some commands.
> I do not fully understand the difference between session and channel.
> If possible please explain a bit.

They are two SSH protocol level concepts, I recommend reading RFC4254
chapter 5 and 6 where channels are explained:

Please note that SSH sessions are different from "terminal sessions"
and "Interactive Sessions" also explained in RFC4254.

An SSH session can be considered to represent the TCP connection that
has been authenticated by the SSH server, usually by one or more of
password, public key and keyboard-interactive credentials. Within one
such SSH session there can be multiple SSH channels, if server policy
permits. You can e.g. take advantage of this in the OpenSSH ssh client
using the "ControlMaster" and "ControlPath" directives. It's a nice
feature of the SSH protocol.

> Is it possible to use &quot;libssh2_channel_exec&quot; in the scenario
> explained above (means in sub-command case) ?

No, that will not work with the type of shell you describe. Your target
device should in fact probably not even allow you to open a channel,
since that application-specific shell is rich in context.

> Does &quot;libssh2_channel_exec&quot; is able to provide all the data
> if command output is very big ?

Large data transfer does work well with all channel types in libssh2,
the function at the center of data transfer is libssh2_channel_read(),
which reads data from open channels. But it does not behave exactly like
the read() system call, and the differences can be tricky to deal with.

Differences have to do with how the SSH protocol can also send other
messages than what you are waiting for (like data for another channel,
or a message unrelated to any channel such as re-keying the SSH session)
and while libssh2 handles them in the background, things like timeout
usually have to be implemented "by hand" in the application - the kernel
APIs such as select() and poll() can't be used, because one TCP connection
can carry many SSH message types, and the kernel doesn't know which bytes
belong to a particular channel. SSH is a very useful protocol, but this
part can make it a little inconvenient in applications.

Try using some of the examples that are included with libssh2, first
unchanged, then move on to change them.

In the end, for an interactive shell like the one you describe, I
think you will have to do a lot of work to create a reliable tool,
including some kind of terminal emulation (but maybe not very much)
to satisfy the expectations of the shell running on the device.

Received on 2018-10-30