scp not tolerant of extraneous shell messages

Dan Kaminsky dan at doxpara.com
Tue Jul 2 04:11:53 EST 2002


Ben Lindstrom wrote:

>You are really looking for sftp which has no shell dependancies.
>
>But in general. No.. Fix your startup scripts.  scp is rcp in a ssh
>wrapper.  and rcp will also fail.
>  
>
I did receive a report a while back stating some shell stuff was getting 
in the way of sftp-server. Lemme see if I can track it down...

Ahhh. Here's the FAQ entry the guy quotes: 
http://www.snailbook.com/faq/sftp-corruption.auto.html

===
ftp and scp2 both actually work by running ssh in a subprocess, to 
connect to the remote host and run the file-transfer server (usually 
named sftp-server). For instance, the commandsftp /server/ might result 
in the following command being run (OpenSSH):

|ssh /server/ -s -oForwardX11=no -oForwardAgent=no -oProtocol=2 sftp|

scp2/sftp and sftp-server use a special file-transfer protocol, which 
they speak over this SSH session. The protocol is in fact based on the 
same packet protocol used by SSH.

In order for this to work, the SSH session must be "clean"  that is, it 
must have on it only information transmitted by the programs at either 
end. What often happens, though, is that there are statements in either 
the system or per-user shell startup files on the server (.bashrc, 
.profile, /etc/csh.csrch,.login, etc.) which output text messages on 
login, intended to be read by humans (like fortune, echo "Hi there!", 
etc.). Such code should only produce output on interactive logins, when 
there is a tty attached to standard input. If it does not make this 
test, it will insert these text messages where they don't belong: in 
this case, polluting the protocol stream between scp2/sftp 
andsftp-server. The first four bytes of the text gets interpreted as a 
32-bit packet length, which will usually be a wildly large number, 
provoking the error message above. Notice that:

|1416586337 decimal = 546F6461 hex = "Toda" ASCII |

suggesting a string beginning "Today..." (or maybe "Thank-you" in 
transliterated Hebrew).

The reason the shell startup files are relevant at all, is that sshd 
employs the user's shell when starting any programs on the user's behalf 
(using e.g. /bin/sh -c "/command/"). This is a Unix tradition, and has 
advantages:

    * The user's usual setup (command aliases, environment variables,
      umask, etc.) are in effect when remote commands are run.
    * The common practice of setting an account's shell to/bin/false to
      disable it will prevent the owner from running any commands,
      should authentication still accidentally succeed for some reason.

There has been a lot of argument about whether this is the right 
behavior, since having sshd instead exec sftp-server directly, without 
the shell, would avoid this frequent problem. I personally feel that 
using the shell is the right thing to do: having startup files that emit 
text messages when there is no user to read them is just a mistake.

SSH2 has a Boolean configuration 
statementAllowCshrcSourcingWithSubsystems, set false by default, which 
causes sshd2 to pass the -f flag to the shell when running subsystem 
programs (sftp-server is run as an SSH-2 "subsystem"). With most shells, 
-f causes the shell to omit the normal startup file processing. This 
prevents the corruption problem, but introduces other difficulties. With 
file transfers, the umask setting is important, and people are confused 
when they find that the umask they set in their ~/.login file works with 
random remote commands (e.g. ssh /server/ touch foo), but is 
mysteriously ignored when using scp2/sftp.

===




More information about the openssh-unix-dev mailing list