ncto

peer-to-peer file transfer using nc, tar and openssl

As xkcd illustrates perfectly, it is somewhat complicated to transfer files peer-to-peer over a network.

Sure, if the endpoint containing the file is running sshd(8), one can transfer files with scp(1) or sftp(1). However, the downside of this approach is that one has to login into the other computer. I don't want to have to login to my computer from one I don't necessarily know is secure.

Solution 1: nc

Thus, my friends and I started to transfer files with nc(1).
For example, lets say HostA wants to transfer a file to HostB. On HostB execute:

$ nc -l 4242 > file

And on HostA:

$ nc HostB 4242 < file

This is a very easy and fast way to exchange a file. However, one of the disadvantages of this approach is that only one file can be transfered at a time and the receiving end needs to type in the file name beforehand.

Solution 2: nc and tar

So we started to use tar(1) in combination with nc. Tar solves both of the aforementioned problems. To do this run on HostB:

$ nc -l 4242 | tar xvf -

And on HostA:

$ tar cvf - files | nc HostB 4242

Solution 3: nc, tar and openssl

Nc in combination with tar is a good solution for a home network. But files sometimes also need to be transfered over not so private networks. Our solution so far offers no security. Encryption can be added by using openssl.
On HostB run:

$ nc -l 4242 | openssl rc4 -d -k password | tar xvf -

And on HostA run:

$ tar cvf - files | openssl rc4 -e -k password | nc HostB 4242

This adds rc4 encryption to the file transfer.

Putting it together: ncto

Now this is a lot to type and to remember. Therefore I've written a script which wraps nc, tar and openssl into an easy to use command line tool, which i call ncto.

To run the same command as above, simply type on HostB:

$ ncto -l 4242
Password: enter password, will not echo

And on HostA:

$ ncto HostB 4242 files
Password: enter password, will not echo

You can of course also send files from the listening side.
HostB:

$ ncto -l 4242 files
Password: enter password, will not echo

HostA:

$ ncto HostB 4242
Password: enter password, will not echo

If you prefer another cipher, specify it with the -c option. And to send without encryption use the -p option.

A note for Linux and Mac users:
If ksh is not available on your system, just change the hashbang to /bin/bash or wherever your bash is hiding. Worked on Ubuntu 10.04 and Debian Squeeze 6.0.
However, Mac OS X's bash has problems interpreting the pattern in the [[ expression ]] command. Just stay with its ksh.