I am writing part of the software that has to execute remote shell command. This command waits for some additional info from stdin in order to continue it's execution.
Here is the remote program test_interactive.sh:
#!/bin/sh
echo -n "Please, enter a string: "
read string # <-- Wait here for the input to come...
if [ -z "$string" ] ; then
echo "1. You entered empty string." 1>&2
else
echo "1. Your string: $string"
fi
At this moment I am initiating the execution of my command with SSH_MSG_CHANNEL_REQUEST exec message. Then after window adjustments and success message, I am sending SSH_MSG_CHANNEL_DATA with the data that I'd like to be pushed into my program's stdin by sshd server. As it turned out, my program doesn't receive anything on stdin.
SSH_MSG_CHANNEL_REQUEST exec causes sshd process to spawn two additional processes sshd(63023) and test_interactive(63024).
The process test_interactive*(63024) has the following file descriptors:
And here is the sequence of messages that leads me to the state, where I'm sending messages and receiving back nothing from my program:
Send: 'SSH_MSG_CHANNEL_OPEN session'
Receive: 'SSH_MSG_CHANNEL_OPEN_CONFIRMATION 0'
Send: 'SSH_MSG_CHANNEL_REQUEST exec'
Receive: 'SSH_MSG_CHANNEL_WINDOW_ADJUST'
Receive: 'SSH_MSG_CHANNEL_SUCCESS'
Receive: 'SSH_MSG_CHANNEL_DATA Please, enter a string:'
Send: 'SSH_MSG_CHANNEL_DATA hello' <-- communication stops here
How should I instruct sshd to push data into stdin that it receives with SSH_MSG_CHANNEL_DATA? I have tried to find it out by looking at the source code of sshd, but it's quite big and I think it will take weeks for me to figure this out :)
The daemon sshd pushes data into stdin if you do the following:
Or more illustratively:
Send: 'SSH_MSG_CHANNEL_REQUEST exec'
Send: 'SSH_MSG_CHANNEL_DATA Hello World'
Send: 'SSH_MSG_CHANNEL_EOF'
Receive: 'SSH_MSG_CHANNEL_DATA Please, enter a string:'
Receive: 'SSH_MSG_CHANNEL_REQUEST exit-status'
Receive: 'SSH_MSG_CHANNEL_DATA Please, enter a string: 1. Your string: Hello\n'
Receive: 'SSH_MSG_CHANNEL_EOF'
Receive: 'SSH_MSG_CHANNEL_CLOSE'
Send: 'SSH_MSG_CHANNEL_CLOSE'
Send: 'SSH_MSG_DISCONNECT'
This doesn't solve the problem, but gives a little bit more information on the sshd's behaviour. I still need to be able to form my message for the program based on what has come to me, not just fire and forget.
By the way, it would be cool to add rfc4254 tag ;) ↓
With the help of the Kenster I have found the answer.
But you need to be careful with what you are sending. In my case, the methods that formed the response message erased '\n' character from the stream. This character was needed for shell function read to proceed.