Strange behaviour surrounding "ssh -T ..." and non-zero exit

W. Michael Petullo mike at flyn.org
Fri Nov 9 15:48:55 AWST 2018


> I am using Dropbear v2017.75 as found on OpenWrt.
> 
> I am building a system around a special shell which exits with the value
> of `1' upon encountering certain errors. Let us assume this shell runs
> on the host "h." My aim is that the following will print `1' if such an
> error occurs (using Dropbear's ssh to Dropbear's sshd):
> 
> 	echo input | ssh -T h; echo $?
> 
> Despite the error occurring, the above command line prints `0' rather
> than `1.' Since this triggers the error, I would expect the latter
> instead.
> 
> When I run this (using Dropbear's ssh to Dropbear's sshd):
> 
> 	ssh -T h; echo $?
> 
> and manually provide the input by typing "input," the result is `1'
> as expected.
> 
> Something from using "-T" and also taking input from a pipe seems to
> cause ssh or sshd to malfunction in the earlier case.
> 
> When I repeat these commands using OpenSSH's ssh to connect to Dropbear's
> sshd, the output is `1' in both cases. This is the expected behavior.
> 
> Does anyone have an idea of what might be causing this? Is there indeed
> a bug related to "-T" plus stdin from a pipe?

After looking at the code, it appears this block in common-channel.c is
the culprit (line 346):

        if (channel->readfd == FD_CLOSED
                        && channel->writefd == FD_CLOSED
                        && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)
                        && !channel->sent_close
                        && close_allowed
                        && !write_pending(channel)) {
                TRACE(("sending close, readfd is closed"))
                send_msg_channel_close(channel);
        }

I think ssh is reaching the EOF on stdin, and then this block causes the
channel to close before it reads the exit code from the distant end.

I do not yet know the code well enough to know if I have this right, but
replacing send_msg_channel_close with send_msg_channel_eof does result in
the correct exit code. Removing this block entirely also causes the same.

Any idea what the correct solution is?

-- 
Mike

:wq


More information about the Dropbear mailing list