I want to write an ssh server which can run a child process and pipe data to/from it. As a prototype, I'm looking to be able to do this:
- Start the server.
- Run:
$ echo "hello world" | ssh -p 2222 127.0.0.1 'wc'
This should work just like echo "hello world" | wc
, except it will run wc
from the ssh server and use pipes to send data between the ssh server and the child process, and finally return the output to the client's ssh client and output it to the terminal.
I'm using thrussh for this, which is a tokio-based ssh framework, but I'm having some trouble wrapping my head around some concepts in thrussh, but I'm also unsure about some of the semantics regarding piping to a child process using tokio's version of Command
.
The server does seem to work in the sense that the client connects to it, it receives the command and data, and from what I can tell the data is passed to wc
, which returns its output -- however, the server fails when trying to write the result back to the client. The h.data()
returns an error, but the error seems to only describes the properties of the output buffer; I can't see it including any hint of what's actually wrong.
Does anyone know what I'm missing?
One of the things which is throwing me for a loop is that thrussh is an async crate, but the actual callbacks aren't async. (I would assume because there's no native support for async trait methods yet). This has caused me to introduce a channel, merely for bridging the non-async and the async world (see child_stdin_tx
). Is there a way to avoid having this?