This is a simple command-line file transfer tool, which allows you to transfer files between two devices you have access to.
The advantage over something like ssh
and scp
is:
-
Neither machine needs to run an SSH server: I've never been comfortable with the risk of misconfiguring the SSH server and leaving myself open to a brute-force password attack.
-
There is no need for an out-of-band exchange of keys or credentials: in my view, having to exchange keys via some other means (e.g. e-mail) would defeat the purpose of a file transfer program.
The advantage over netcat
is:
-
No additional work is required to ensure the file or directory is encrypted in transit.
-
You don't have to remember how to properly pipe files to the commands.
The recommended way to create an executable is to clone the repository and build from source with cargo build
.
If you use the Nix package manager (or NixOS), you can also simply call:
nix run github:ssddq/transfer
However, if you care at all about security, this would be extremely ill-advised (for obvious reasons).
You must first run the program on the receiving device with
transfer receive <out>
where is the output path. The file or directory received will be placed inside ; use .
to place them in the current directory. If a file with the same name already exists it will be overwritten without notice or confirmation.
To listen for connections on a specific port, run
transfer receive -p <port> <out>
The default value of -p
is 0
, which means that an unused port will be selected by the operating system.
On your other device, you must then run
transfer send <ip> <port> <path>
The public IP address and port on the receiving device will have been displayed, and you can simply copy the command provided.
You will be required to manually confirm the connection on both devices (by entering y
or n
); each side will terminate (independently) once it has completed.
There are two rather significant limitations:
-
The receiving device cannot have a firewall: the operating system must allow incoming TCP connections on whichever port the program is listening on. For example, you will not be able to receive files on a standard NixOS installation unless you have explicitly disabled disabled the firewall with
networking.firewall.enable = false;
in your configuration file.
- In the (almost guaranteed) event that the receiving device is behind a router, you must either a) have the device you wish to send files from on the same local network (and then use its local IP address) or b) set up port forwarding on your router for whichever port the receiving device is listening on.
You may observe either a connection timeout or refusal in either case, depending on how your router or device firewall handles unsolicited incoming TCP traffic.
Comments: It's certainly possible to make a best-effort attempt at hole-punching to try to initiate a connection, but I didn't feel this was worth the additional complexity at this time. Alternatively, it would be far more reliable (and completely trivial) to set up a central relay server that simply receives and transmits the files between its clients, but I'd rather not have to upkeep that.
In lieu of an out-of-band exchange of keys, the program constructs a shared secret which you are required to manually compare on both devices. Note that you must have access to both devices (physical or otherwise) to provide confirmation; skipping this would allow for a trivial man-in-the-middle attack.
The shared secret is generated by a P-384 Diffie-Hellman key exchange. The program uses HKDF to extract a 256-bit key from this shared secret, which is then used as an AES cipher. After receiving confirmation from the user that the pairs of public keys match, the file or directory is then zipped, encrypted with this cipher and transferred to the other device.
Warning: You should not use this to exchange sensitive data between your devices. There are no serious guarantees about the security of the connection or the integrity of the encryption algorithm, for several reasons:
-
As of this writing, at least some of the cryptography libraries used have not been independently audited.
-
It is quite difficult to reliably verify that the keys match; the human tendency to verify only an initial or terminal segment of the secret is a serious attack vector. This could be alleviated by providing e.g. a hashed visual representation of the keys, but I've avoided doing this for the sake of simplicity.
-
I did not spend much time thinking about other possible attack vectors.
-
The code I've written has not been independetly proofread.
That said, while you should generally not expect any meaningful security from this program, please do file an issue if you notice anything specific.