From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.1) Gecko/20020827 Description of problem: When using scp over an fsh proxy, if I try to copy more than one file, the second copy fails with the error message: ssh_exchange_identification: Connection closed by remote host Version-Release number of selected component (if applicable): fsh-1.2-3 How reproducible: Always Steps to Reproduce: I have the following in my .ssh/config file: Host bastion-fsh HostName bastion.looney.com ForwardX11 no ForwardAgent no KeepAlive yes Host bastion.looney.com ProxyCommand none Host *.looney.com ProxyCommand fsh bastion-fsh exec /usr/bin/nc %h %p Start up fshd explicitly: $ fshd bastion-fsh S/Key one time passwords are in effect. Challenge: s/key 9496 basti1729 Password: Could not chdir to home directory /home/jimb: No such file or directory Connection established Then, I try to scp two files from a remote host: scp host.looney.com:nit{1,2}.c . Actual Results: The first file is copied over successfully, but the second fails: nit1.c 100% 1308 1.3KB/s 00:01 ssh_exchange_identification: Connection closed by remote host Expected Results: I'd like both files to be copied over successfully: nit1.c 100% 1308 1.3KB/s 00:01 nit2.c 100% 1309 1.3KB/s 00:01 Additional info: The problem is in the way the local fshd tries to reuse its session numbers. The output from fshd when the scp fails is like this: 1 start 1 $ exec /usr/bin/nc host.looney.com 22 1 start 1 $ exec /usr/bin/nc host.looney.com 22 1 EOS (and then, after a long pause) 1 EOS The bug is in fshd.py: in the 'client' class, any error from fshlib.read or fshlib.write will cause self.socket to be set to -1. If that happens, is_closed will return true, and thus the loop in class 'fshd', method 'toploop' that assigns numbers to new sessions will consider the number of the session that got the error to be reusable. That's all reasonable, but the in.fshd on the bastion host doesn't know that the session number has been reused. It doesn't know that the local fshd got an error writing back to one of its clients, so it considers the session still alive. The fix is to only reuse session numbers after everyone agrees the session is finished: the remote in.fshd must have sent an eos, and any queued writes must have been completed. Fortunately, 'client' already represents exactly the information we need: self.socket is -1 when the local side agrees everything is taken care of, and self.pending_close reflects whether in.fshd has sent an eos. Changing the definition of the 'client' 'is_closed' method to: return self.socket == -1 and self.pending_close allows the scp to work properly. I have a patch that fixes this problem, which I'll attach if I can persuade Bugzilla to let me do so.
Created attachment 103870 [details] patch to fix fshd client session reuse behavior Works for me.
Built into 1.2-5 which should turn up in rawhide some time soon, probably after FC3t2. Thanks for the patch. Note that fsh is basically going to be obsoleted by OpenSSH itself. See the documentation of the new ControlMaster and ControlSocket options in OpenSSH 3.9.