Awesome
sftp-streams
Attempt to implement the SSH File Transfer Protocol.
Status
There are two small binaries: sftp-mitm
and sftp-mem
.
sftp-mitm
can sit between sshd
and the SFTP SSH subsystem (e.g. on Ubuntu
this is /usr/lib/openssh/sftp-server
). It parses the packets exchanged by a
regular client and the real SFTP program on the server, and display them.
sftp-mem
implements a few commands. Those commands are exercised in
test-sftp-mem.sh
and can be compared to test-sftp-mitm.sh
. They can be seen
in test-batch.txt.
test-sftp-sshs.sh
uses SSHFS to talk to sftp-mem
.
Docker image
Paths are hard-coded in the executable. There is a Dockerfile to create an
image that matches the expectations. Before building the image, you need to
provide a public SSH key insecure_id_rsa.pub
and the sftp-mitm
binary (put
them in the images/sftp-mitm
directory). Same for sftp-mem
.
Notes
I have started to implement this package by looking at http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13 (which describes protocol version 6) then I have switched to http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02 when I saw that my client was using protocol version 3.
The version of sftp
(i.e. the client) I used defaults to protocol version 3.
I have not tried protocol versions 1 and 2 (accessible with the -1
and -2
flags).
The client can re-use packet IDs very quickly (e.g. after 3 or 4 requests).
SSH_FXP_READ
packets request 32768 bytes at a time. I think I can use the
-B
flag to influence that size.
If the server response includes less than the requested size, the client will
issue a second request to try to get the "missing" bytes, but not again 32768
bytes. It does so even if the preceding SSH_FXP_STAT
request lets it know the
size of the file and thus that the file was complete.
It is necessary to create a directory that you plan to transfer with put -r
:
> mkdir some-directory
> put -r some-directory
otherwise the server fails. I think the reason is that the client first issues
SSH_FXP_REALPATH
to get the correct path of the directory before transfering
it. That requests fail because the path doesn't exist yet.
Actually, by preceding the put -r
by mkdir
, everything (from the user point
of view) works. In reality, the put -r
also tries to do a SSH_FXP_MKDIR
which fails because the directory already exists.
For debugging, I could have used the -D
flag instead of passing through sshd.
Instead of configuring sshd's subsystem to use the sftp-mitm
program, the
-s
option could have been used.